diff --git a/CotEditor.xcodeproj/project.pbxproj b/CotEditor.xcodeproj/project.pbxproj index 8b88560f4..5d1630af6 100644 --- a/CotEditor.xcodeproj/project.pbxproj +++ b/CotEditor.xcodeproj/project.pbxproj @@ -378,8 +378,6 @@ 2A6876A92963DE38006257A6 /* TextFinderSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6876A72963DE38006257A6 /* TextFinderSettings.swift */; }; 2A6876AB29641547006257A6 /* MultipleReplacePanelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6876AA29641547006257A6 /* MultipleReplacePanelController.swift */; }; 2A6876AC29641547006257A6 /* MultipleReplacePanelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6876AA29641547006257A6 /* MultipleReplacePanelController.swift */; }; - 2A6876AE296505BC006257A6 /* FirstResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6876AD296505BC006257A6 /* FirstResponder.swift */; }; - 2A6876AF296505BC006257A6 /* FirstResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6876AD296505BC006257A6 /* FirstResponder.swift */; }; 2A6C8E3221E1187A003966ED /* EditorTextView+CursorMovement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6C8E3121E1187A003966ED /* EditorTextView+CursorMovement.swift */; }; 2A6C8E3321E1187A003966ED /* EditorTextView+CursorMovement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A6C8E3121E1187A003966ED /* EditorTextView+CursorMovement.swift */; }; 2A6E3F3D19B5218300A63E97 /* CotEditor.help in Resources */ = {isa = PBXBuildFile; fileRef = 2A6E3F3C19B5218300A63E97 /* CotEditor.help */; }; @@ -1086,7 +1084,6 @@ 2A68722E288A5C44006D6B41 /* DraggableHostingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggableHostingView.swift; sourceTree = ""; }; 2A6876A72963DE38006257A6 /* TextFinderSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFinderSettings.swift; sourceTree = ""; }; 2A6876AA29641547006257A6 /* MultipleReplacePanelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipleReplacePanelController.swift; sourceTree = ""; }; - 2A6876AD296505BC006257A6 /* FirstResponder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstResponder.swift; sourceTree = ""; }; 2A6C8E3121E1187A003966ED /* EditorTextView+CursorMovement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EditorTextView+CursorMovement.swift"; sourceTree = ""; }; 2A6E3F3C19B5218300A63E97 /* CotEditor.help */ = {isa = PBXFileReference; lastKnownFileType = folder; path = CotEditor.help; sourceTree = ""; }; 2A6F0E071B5500E100C2D03C /* CotEditor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CotEditor.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2373,7 +2370,6 @@ isa = PBXGroup; children = ( 2AB1BD1E287D747200C6FEAF /* SizeGetter.swift */, - 2A6876AD296505BC006257A6 /* FirstResponder.swift */, ); name = Helpers; sourceTree = ""; @@ -2976,7 +2972,6 @@ 2A231A2E1E7BE8B700C2A909 /* FindProgress.swift in Sources */, 2A5D13111D1EE66500D38E6A /* FindProgressView.swift in Sources */, 2AF98CAB294B9488009AD47F /* FindSettingsView.swift in Sources */, - 2A6876AE296505BC006257A6 /* FirstResponder.swift in Sources */, 2AFFA7C32B16E93B005652CD /* FormatSettingsView.swift in Sources */, 2A65EC262B80C01B008096C5 /* FontPicker.swift in Sources */, 2A19AF862AE0D15300EFFDCB /* FormPopUpButton.swift in Sources */, @@ -3344,7 +3339,6 @@ 2A231A2D1E7BE8B700C2A909 /* FindProgress.swift in Sources */, 2A5D13101D1EE66500D38E6A /* FindProgressView.swift in Sources */, 2AF98CAC294B9488009AD47F /* FindSettingsView.swift in Sources */, - 2A6876AF296505BC006257A6 /* FirstResponder.swift in Sources */, 2A65EC272B80C01B008096C5 /* FontPicker.swift in Sources */, 2A19AF872AE0D15300EFFDCB /* FormPopUpButton.swift in Sources */, 2AFFA7C42B16E93B005652CD /* FormatSettingsView.swift in Sources */, @@ -3888,7 +3882,7 @@ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; - OTHER_SWIFT_FLAGS = "-enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature ExistentialAny -enable-upcoming-feature ForwardTrailingClosures -enable-upcoming-feature ImplicitOpenExistentials -enable-upcoming-feature DisableOutwardActorInference"; + OTHER_SWIFT_FLAGS = "-enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature ExistentialAny -enable-upcoming-feature ForwardTrailingClosures -enable-upcoming-feature ImplicitOpenExistentials -enable-upcoming-feature DisableOutwardActorInference -enable-upcoming-feature IsolatedDefaultValues"; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = macosx; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; @@ -3952,7 +3946,7 @@ MACOSX_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; - OTHER_SWIFT_FLAGS = "-enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature ExistentialAny -enable-upcoming-feature ForwardTrailingClosures -enable-upcoming-feature ImplicitOpenExistentials -enable-upcoming-feature DisableOutwardActorInference"; + OTHER_SWIFT_FLAGS = "-enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature ExistentialAny -enable-upcoming-feature ForwardTrailingClosures -enable-upcoming-feature ImplicitOpenExistentials -enable-upcoming-feature DisableOutwardActorInference -enable-upcoming-feature IsolatedDefaultValues"; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/CotEditor/Sources/FindPanelButtonView.swift b/CotEditor/Sources/FindPanelButtonView.swift index 5fd706385..e43e13c31 100644 --- a/CotEditor/Sources/FindPanelButtonView.swift +++ b/CotEditor/Sources/FindPanelButtonView.swift @@ -27,11 +27,6 @@ import SwiftUI struct FindPanelButtonView: View { - @FirstResponder private var firstResponder - - - // MARK: View - var body: some View { HStack(alignment: .bottom) { @@ -80,7 +75,6 @@ struct FindPanelButtonView: View { .labelStyle(.iconOnly) .frame(width: 70) } - .responderChain(to: self.firstResponder) .padding(.top, 8) .scenePadding([.horizontal, .bottom]) } @@ -88,9 +82,16 @@ struct FindPanelButtonView: View { // MARK: Private Methods + /// Send a text finder action message to the legacy responder-chain. + /// + /// - Parameter action: The `TextFinder.Action` to perform. @MainActor private func performAction(_ action: TextFinder.Action) { - self.firstResponder.performAction(#selector((any TextFinderClient).performEditorTextFinderAction), tag: action.rawValue) + // create a dummy sender for tag + let sender = NSControl() + sender.tag = action.rawValue + + NSApp.sendAction(#selector((any TextFinderClient).performEditorTextFinderAction), to: nil, from: sender) } } diff --git a/CotEditor/Sources/FirstResponder.swift b/CotEditor/Sources/FirstResponder.swift deleted file mode 100644 index 6011e0c56..000000000 --- a/CotEditor/Sources/FirstResponder.swift +++ /dev/null @@ -1,86 +0,0 @@ -// -// FirstResponder.swift -// -// CotEditor -// https://coteditor.com -// -// Created by 1024jp on 2023-01-04. -// -// --------------------------------------------------------------------------- -// -// © 2023 1024jp -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -import AppKit -import SwiftUI - -extension View { - - /// Provides access to the Cocoa responder chain. - /// - /// - Parameter firstResponder: The first responder. - func responderChain(to firstResponder: FirstResponder) -> some View { - - self.background(MessageSender(responder: firstResponder)) - } -} - - - -@propertyWrapper -@MainActor final class FirstResponder { - - fileprivate weak var sender: NSControl? - - - var wrappedValue: FirstResponder { - - self - } - - - /// Sends the action message to the first responder, namely `nil`. - /// - /// - Parameters: - /// - action: The action message to send. - /// - tag: The tag to be owned by the message sender. - /// - Returns: `true` if the action was successfully sent; otherwise `false`. - @discardableResult - func performAction(_ action: Selector, tag: Int = 0) -> Bool { - - self.sender?.tag = tag - - return NSApp.sendAction(action, to: nil, from: self.sender) - } -} - - - -private struct MessageSender: NSViewRepresentable { - - let responder: FirstResponder - - - func makeNSView(context: Context) -> NSControl { - - NSControl() - } - - - func updateNSView(_ nsView: NSControl, context: Context) { - - self.responder.sender = nsView - } -}