@@ -576,7 +576,7 @@ public final class AppKitBackend: AppBackend {
576576 }
577577
578578 public func createButton( ) -> Widget {
579- return NSButton ( title: " " , target: nil , action: nil )
579+ return NSCustomButton ( title: " " , target: nil , action: nil )
580580 }
581581
582582 public func updateButton(
@@ -585,43 +585,45 @@ public final class AppKitBackend: AppBackend {
585585 environment: EnvironmentValues ,
586586 action: @escaping ( ) -> Void
587587 ) {
588- let button = button as! NSButton
588+ let button = button as! NSCustomButton
589589 button. attributedTitle = Self . attributedString (
590590 for: label,
591591 in: environment. with ( \. multilineTextAlignment, . center)
592592 )
593593 button. bezelStyle = . regularSquare
594594 button. appearance = environment. colorScheme. nsAppearance
595595 button. isEnabled = environment. isEnabled
596+ button. canBeFocused = environment. isFocusable
596597 button. onAction = { _ in
597598 action ( )
598599 }
599600 }
600601
601602 public func createSwitch( ) -> Widget {
602- return NSSwitch ( )
603+ return NSCustomSwitch ( )
603604 }
604605
605606 public func updateSwitch(
606607 _ toggleSwitch: Widget ,
607608 environment: EnvironmentValues ,
608609 onChange: @escaping ( Bool ) -> Void
609610 ) {
610- let toggleSwitch = toggleSwitch as! NSSwitch
611+ let toggleSwitch = toggleSwitch as! NSCustomSwitch
611612 toggleSwitch. isEnabled = environment. isEnabled
613+ toggleSwitch. canBeFocused = environment. isFocusable
612614 toggleSwitch. onAction = { toggleSwitch in
613- let toggleSwitch = toggleSwitch as! NSSwitch
615+ let toggleSwitch = toggleSwitch as! NSCustomSwitch
614616 onChange ( toggleSwitch. state == . on)
615617 }
616618 }
617619
618620 public func setState( ofSwitch toggleSwitch: Widget , to state: Bool ) {
619- let toggleSwitch = toggleSwitch as! NSSwitch
621+ let toggleSwitch = toggleSwitch as! NSCustomSwitch
620622 toggleSwitch. state = state ? . on : . off
621623 }
622624
623625 public func createToggle( ) -> Widget {
624- let toggle = NSButton ( )
626+ let toggle = NSCustomButton ( )
625627 toggle. setButtonType ( . pushOnPushOff)
626628 return toggle
627629 }
@@ -632,47 +634,49 @@ public final class AppKitBackend: AppBackend {
632634 environment: EnvironmentValues ,
633635 onChange: @escaping ( Bool ) -> Void
634636 ) {
635- let toggle = toggle as! NSButton
637+ let toggle = toggle as! NSCustomButton
636638 toggle. attributedTitle = Self . attributedString (
637639 for: label,
638640 in: environment. with ( \. multilineTextAlignment, . center)
639641 )
640642 toggle. isEnabled = environment. isEnabled
643+ toggle. canBeFocused = environment. isFocusable
641644 toggle. onAction = { toggle in
642- let toggle = toggle as! NSButton
645+ let toggle = toggle as! NSCustomButton
643646 onChange ( toggle. state == . on)
644647 }
645648 }
646649
647650 public func setState( ofToggle toggle: Widget , to state: Bool ) {
648- let toggle = toggle as! NSButton
651+ let toggle = toggle as! NSCustomButton
649652 toggle. state = state ? . on : . off
650653 }
651654
652655 public func createCheckbox( ) -> Widget {
653- NSButton ( checkboxWithTitle: " " , target: nil , action: nil )
656+ NSCustomButton ( checkboxWithTitle: " " , target: nil , action: nil )
654657 }
655658
656659 public func updateCheckbox(
657660 _ checkbox: Widget ,
658661 environment: EnvironmentValues ,
659662 onChange: @escaping ( Bool ) -> Void
660663 ) {
661- let checkbox = checkbox as! NSButton
664+ let checkbox = checkbox as! NSCustomButton
662665 checkbox. isEnabled = environment. isEnabled
666+ checkbox. canBeFocused = environment. isFocusable
663667 checkbox. onAction = { toggle in
664- let checkbox = toggle as! NSButton
668+ let checkbox = toggle as! NSCustomButton
665669 onChange ( checkbox. state == . on)
666670 }
667671 }
668672
669673 public func setState( ofCheckbox checkbox: Widget , to state: Bool ) {
670- let toggle = checkbox as! NSButton
674+ let toggle = checkbox as! NSCustomButton
671675 toggle. state = state ? . on : . off
672676 }
673677
674678 public func createSlider( ) -> Widget {
675- return NSSlider ( )
679+ return NSCustomSlider ( )
676680 }
677681
678682 public func updateSlider(
@@ -684,23 +688,24 @@ public final class AppKitBackend: AppBackend {
684688 onChange: @escaping ( Double ) -> Void
685689 ) {
686690 // TODO: Implement decimalPlaces
687- let slider = slider as! NSSlider
691+ let slider = slider as! NSCustomSlider
688692 slider. minValue = minimum
689693 slider. maxValue = maximum
690694 slider. onAction = { slider in
691- let slider = slider as! NSSlider
695+ let slider = slider as! NSCustomSlider
692696 onChange ( slider. doubleValue)
693697 }
698+ slider. canBeFocused = environment. isFocusable
694699 slider. isEnabled = environment. isEnabled
695700 }
696701
697702 public func setValue( ofSlider slider: Widget , to value: Double ) {
698- let slider = slider as! NSSlider
703+ let slider = slider as! NSCustomSlider
699704 slider. doubleValue = value
700705 }
701706
702707 public func createPicker( ) -> Widget {
703- return NSPopUpButton ( )
708+ return NSCustomPopUpButton ( )
704709 }
705710
706711 public func updatePicker(
@@ -709,7 +714,7 @@ public final class AppKitBackend: AppBackend {
709714 environment: EnvironmentValues ,
710715 onChange: @escaping ( Int ? ) -> Void
711716 ) {
712- let picker = picker as! NSPopUpButton
717+ let picker = picker as! NSCustomPopUpButton
713718 picker. isEnabled = environment. isEnabled
714719 picker. menu? . removeAllItems ( )
715720 for option in options {
@@ -718,14 +723,15 @@ public final class AppKitBackend: AppBackend {
718723 picker. menu? . addItem ( item)
719724 }
720725 picker. onAction = { picker in
721- let picker = picker as! NSPopUpButton
726+ let picker = picker as! NSCustomPopUpButton
722727 onChange ( picker. indexOfSelectedItem)
723728 }
729+ picker. canBeFocused = environment. isFocusable
724730 picker. bezelStyle = . regularSquare
725731 }
726732
727733 public func setSelectedOption( ofPicker picker: Widget , to selectedOption: Int ? ) {
728- let picker = picker as! NSPopUpButton
734+ let picker = picker as! NSCustomPopUpButton
729735 if let index = selectedOption {
730736 picker. selectItem ( at: index)
731737 } else {
@@ -760,6 +766,7 @@ public final class AppKitBackend: AppBackend {
760766 onChange ( textField. stringValue)
761767 }
762768 textField. onSubmit = onSubmit
769+ textField. canBeFocused = environment. isFocusable
763770
764771 if #available( macOS 14 , * ) {
765772 textField. contentType =
@@ -813,6 +820,7 @@ public final class AppKitBackend: AppBackend {
813820 }
814821 textEditor. appearance = environment. colorScheme. nsAppearance
815822 textEditor. isEditable = environment. isEnabled
823+ textEditor. canBeFocused = environment. isFocusable
816824
817825 if #available( macOS 14 , * ) {
818826 textEditor. contentType =
@@ -1963,11 +1971,49 @@ final class ObjectAssociation<T: Any> {
19631971 }
19641972}
19651973
1974+ final class NSCustomButton : NSButton {
1975+ var canBeFocused : Bool = true
1976+
1977+ override var acceptsFirstResponder : Bool {
1978+ return canBeFocused
1979+ }
1980+ }
1981+
1982+ final class NSCustomSlider : NSSlider {
1983+ var canBeFocused : Bool = true
1984+
1985+ override var acceptsFirstResponder : Bool {
1986+ return canBeFocused
1987+ }
1988+ }
1989+
1990+ final class NSCustomSwitch : NSSwitch {
1991+ var canBeFocused : Bool = true
1992+
1993+ override var acceptsFirstResponder : Bool {
1994+ return canBeFocused
1995+ }
1996+ }
1997+
1998+ final class NSCustomPopUpButton : NSPopUpButton {
1999+ var canBeFocused : Bool = true
2000+
2001+ override var acceptsFirstResponder : Bool {
2002+ return canBeFocused
2003+ }
2004+ }
2005+
19662006class NSObservableTextField : NSTextField {
19672007 override func textDidChange( _ notification: Notification ) {
19682008 onEdit ? ( self )
19692009 }
19702010
2011+ var canBeFocused : Bool = true
2012+
2013+ override var acceptsFirstResponder : Bool {
2014+ return canBeFocused
2015+ }
2016+
19712017 var onEdit : ( ( NSTextField ) -> Void ) ?
19722018 var _onSubmitAction = Action ( { } )
19732019 var onSubmit : ( ) -> Void {
@@ -1987,6 +2033,12 @@ class NSObservableTextView: NSTextView, NSTextViewDelegate {
19872033 onEdit ? ( self )
19882034 }
19892035
2036+ var canBeFocused : Bool = true
2037+
2038+ override var acceptsFirstResponder : Bool {
2039+ return canBeFocused
2040+ }
2041+
19902042 var onEdit : ( ( NSTextView ) -> Void ) ?
19912043}
19922044
0 commit comments