Keyboard shortcuts
This commit is contained in:
@@ -21,5 +21,55 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
{
|
{
|
||||||
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
|
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func buildMenu(with builder: UIMenuBuilder) {
|
||||||
|
let fileCommands = [
|
||||||
|
// Open Location...
|
||||||
|
UIKeyCommand(
|
||||||
|
modifiers: .command, input: "L",
|
||||||
|
title: "Open Location",
|
||||||
|
action: #selector(ShortcutResponder.focusURLBar)
|
||||||
|
),
|
||||||
|
|
||||||
|
// Go Back
|
||||||
|
UIKeyCommand(
|
||||||
|
modifiers: .command, input: "[",
|
||||||
|
title: "Go Back",
|
||||||
|
action: #selector(ShortcutResponder.goBack)
|
||||||
|
),
|
||||||
|
|
||||||
|
// Go Forward
|
||||||
|
UIKeyCommand(
|
||||||
|
modifiers: .command, input: "]",
|
||||||
|
title: "Go Forward",
|
||||||
|
action: #selector(ShortcutResponder.goForward)
|
||||||
|
),
|
||||||
|
|
||||||
|
// Create Tab
|
||||||
|
UIKeyCommand(
|
||||||
|
modifiers: .command, input: "T",
|
||||||
|
title: "New Tab",
|
||||||
|
action: #selector(ShortcutResponder.createTab)
|
||||||
|
),
|
||||||
|
|
||||||
|
// Previous Tab
|
||||||
|
UIKeyCommand(
|
||||||
|
modifiers: [.command, .shift], input: "[",
|
||||||
|
title: "Previous Tab",
|
||||||
|
action: #selector(ShortcutResponder.previousTab)
|
||||||
|
),
|
||||||
|
|
||||||
|
// Next Tab
|
||||||
|
UIKeyCommand(
|
||||||
|
modifiers: [.command, .shift], input: "]",
|
||||||
|
title: "Next Tab",
|
||||||
|
action: #selector(ShortcutResponder.nextTab)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
builder.replaceChildren(ofMenu: .file) { children in
|
||||||
|
return fileCommands + children
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import UniformTypeIdentifiers
|
|||||||
class BrowserViewController: UIViewController, WKNavigationDelegate, WKUIDelegate,
|
class BrowserViewController: UIViewController, WKNavigationDelegate, WKUIDelegate,
|
||||||
UITextFieldDelegate, ScriptPolicyViewControllerDelegate,
|
UITextFieldDelegate, ScriptPolicyViewControllerDelegate,
|
||||||
UIPopoverPresentationControllerDelegate, TabDelegate, TabPickerViewControllerDelegate,
|
UIPopoverPresentationControllerDelegate, TabDelegate, TabPickerViewControllerDelegate,
|
||||||
AutocompleteViewControllerDelegate
|
AutocompleteViewControllerDelegate, ShortcutResponder
|
||||||
{
|
{
|
||||||
let browserView = BrowserView()
|
let browserView = BrowserView()
|
||||||
var tab: Tab { didSet { didChangeTab(tab) } }
|
var tab: Tab { didSet { didChangeTab(tab) } }
|
||||||
@@ -428,4 +428,39 @@ class BrowserViewController: UIViewController, WKNavigationDelegate, WKUIDelegat
|
|||||||
tab.beginLoadingURL(item.url)
|
tab.beginLoadingURL(item.url)
|
||||||
autocompleteViewController.view.isHidden = true
|
autocompleteViewController.view.isHidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Keyboard shortcuts
|
||||||
|
|
||||||
|
func focusURLBar(_ sender: Any?) {
|
||||||
|
toolbarController.urlBar.textField.becomeFirstResponder()
|
||||||
|
}
|
||||||
|
|
||||||
|
func goBack(_ sender: Any?) {
|
||||||
|
tab.webView.goBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
func goForward(_ sender: Any?) {
|
||||||
|
tab.webView.goForward()
|
||||||
|
}
|
||||||
|
|
||||||
|
func createTab(_ sender: Any?) {
|
||||||
|
let newTab = tabController.createNewTab(url: nil)
|
||||||
|
self.tab = newTab
|
||||||
|
}
|
||||||
|
|
||||||
|
func previousTab(_ sender: Any?) {
|
||||||
|
if let tabIndex = tabController.tabs.firstIndex(of: self.tab) {
|
||||||
|
if tabIndex - 1 >= 0 {
|
||||||
|
self.tab = tabController.tabs[tabIndex - 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func nextTab(_ sender: Any?) {
|
||||||
|
if let tabIndex = tabController.tabs.firstIndex(of: self.tab) {
|
||||||
|
if tabIndex + 1 < tabController.tabs.count {
|
||||||
|
self.tab = tabController.tabs[tabIndex + 1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
App/KeyboardShortcuts.swift
Normal file
29
App/KeyboardShortcuts.swift
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// KeyboardShortcuts.swift
|
||||||
|
// App
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 9/21/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objc
|
||||||
|
protocol ShortcutResponder: class {
|
||||||
|
@objc
|
||||||
|
optional func focusURLBar(_ sender: Any?)
|
||||||
|
|
||||||
|
@objc
|
||||||
|
optional func goBack(_ sender: Any?)
|
||||||
|
|
||||||
|
@objc
|
||||||
|
optional func goForward(_ sender: Any?)
|
||||||
|
|
||||||
|
@objc
|
||||||
|
optional func createTab(_ sender: Any?)
|
||||||
|
|
||||||
|
@objc
|
||||||
|
optional func previousTab(_ sender: Any?)
|
||||||
|
|
||||||
|
@objc
|
||||||
|
optional func nextTab(_ sender: Any?)
|
||||||
|
}
|
||||||
15
App/Utilities/UIKeyCommand+ConvInit.swift
Normal file
15
App/Utilities/UIKeyCommand+ConvInit.swift
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// UIKeyCommand+ConvInit.swift
|
||||||
|
// App
|
||||||
|
//
|
||||||
|
// Created by James Magahern on 9/21/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension UIKeyCommand {
|
||||||
|
convenience init(modifiers: UIKeyModifierFlags, input: String, title: String, action: Selector) {
|
||||||
|
self.init(input: input, modifierFlags: modifiers, action: action)
|
||||||
|
self.title = title
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,6 +37,8 @@
|
|||||||
1ADFF4CD24CBB0C8006DC7AE /* ScriptPolicyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4CC24CBB0C8006DC7AE /* ScriptPolicyViewController.swift */; };
|
1ADFF4CD24CBB0C8006DC7AE /* ScriptPolicyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4CC24CBB0C8006DC7AE /* ScriptPolicyViewController.swift */; };
|
||||||
1ADFF4D024CBBCD1006DC7AE /* ScriptPolicyControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4CF24CBBCD1006DC7AE /* ScriptPolicyControl.swift */; };
|
1ADFF4D024CBBCD1006DC7AE /* ScriptPolicyControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ADFF4CF24CBBCD1006DC7AE /* ScriptPolicyControl.swift */; };
|
||||||
CD7A8915251975B70075991E /* AutocompleteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7A8914251975B70075991E /* AutocompleteViewController.swift */; };
|
CD7A8915251975B70075991E /* AutocompleteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7A8914251975B70075991E /* AutocompleteViewController.swift */; };
|
||||||
|
CD7A89172519872D0075991E /* KeyboardShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7A89162519872D0075991E /* KeyboardShortcuts.swift */; };
|
||||||
|
CD7A8919251989C90075991E /* UIKeyCommand+ConvInit.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD7A8918251989C90075991E /* UIKeyCommand+ConvInit.swift */; };
|
||||||
CD853BCE24E7763900D2BDCC /* BrowserHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCD24E7763900D2BDCC /* BrowserHistory.swift */; };
|
CD853BCE24E7763900D2BDCC /* BrowserHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCD24E7763900D2BDCC /* BrowserHistory.swift */; };
|
||||||
CD853BD124E778B800D2BDCC /* History.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCF24E778B800D2BDCC /* History.xcdatamodeld */; };
|
CD853BD124E778B800D2BDCC /* History.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = CD853BCF24E778B800D2BDCC /* History.xcdatamodeld */; };
|
||||||
CD853BD424E77BF900D2BDCC /* HistoryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD853BD324E77BF900D2BDCC /* HistoryItem.swift */; };
|
CD853BD424E77BF900D2BDCC /* HistoryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD853BD324E77BF900D2BDCC /* HistoryItem.swift */; };
|
||||||
@@ -106,6 +108,8 @@
|
|||||||
1ADFF4CC24CBB0C8006DC7AE /* ScriptPolicyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptPolicyViewController.swift; sourceTree = "<group>"; };
|
1ADFF4CC24CBB0C8006DC7AE /* ScriptPolicyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptPolicyViewController.swift; sourceTree = "<group>"; };
|
||||||
1ADFF4CF24CBBCD1006DC7AE /* ScriptPolicyControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptPolicyControl.swift; sourceTree = "<group>"; };
|
1ADFF4CF24CBBCD1006DC7AE /* ScriptPolicyControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptPolicyControl.swift; sourceTree = "<group>"; };
|
||||||
CD7A8914251975B70075991E /* AutocompleteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteViewController.swift; sourceTree = "<group>"; };
|
CD7A8914251975B70075991E /* AutocompleteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteViewController.swift; sourceTree = "<group>"; };
|
||||||
|
CD7A89162519872D0075991E /* KeyboardShortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardShortcuts.swift; sourceTree = "<group>"; };
|
||||||
|
CD7A8918251989C90075991E /* UIKeyCommand+ConvInit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIKeyCommand+ConvInit.swift"; sourceTree = "<group>"; };
|
||||||
CD853BCD24E7763900D2BDCC /* BrowserHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserHistory.swift; sourceTree = "<group>"; };
|
CD853BCD24E7763900D2BDCC /* BrowserHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserHistory.swift; sourceTree = "<group>"; };
|
||||||
CD853BD024E778B800D2BDCC /* History.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = History.xcdatamodel; sourceTree = "<group>"; };
|
CD853BD024E778B800D2BDCC /* History.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = History.xcdatamodel; sourceTree = "<group>"; };
|
||||||
CD853BD324E77BF900D2BDCC /* HistoryItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryItem.swift; sourceTree = "<group>"; };
|
CD853BD324E77BF900D2BDCC /* HistoryItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryItem.swift; sourceTree = "<group>"; };
|
||||||
@@ -194,6 +198,7 @@
|
|||||||
children = (
|
children = (
|
||||||
1ADFF45F24C7DE53006DC7AE /* AppDelegate.swift */,
|
1ADFF45F24C7DE53006DC7AE /* AppDelegate.swift */,
|
||||||
1ADFF46124C7DE53006DC7AE /* SceneDelegate.swift */,
|
1ADFF46124C7DE53006DC7AE /* SceneDelegate.swift */,
|
||||||
|
CD7A89162519872D0075991E /* KeyboardShortcuts.swift */,
|
||||||
CD7A89132519759D0075991E /* Autocomplete */,
|
CD7A89132519759D0075991E /* Autocomplete */,
|
||||||
1ADFF47A24C7E176006DC7AE /* Backend */,
|
1ADFF47A24C7E176006DC7AE /* Backend */,
|
||||||
1ADFF47724C7DFE8006DC7AE /* Browser View */,
|
1ADFF47724C7DFE8006DC7AE /* Browser View */,
|
||||||
@@ -272,6 +277,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
1ADFF4C224CA6AF6006DC7AE /* Geometry.swift */,
|
1ADFF4C224CA6AF6006DC7AE /* Geometry.swift */,
|
||||||
|
CD7A8918251989C90075991E /* UIKeyCommand+ConvInit.swift */,
|
||||||
1ADFF4C624CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift */,
|
1ADFF4C624CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift */,
|
||||||
1AB88F0524D4D3A90006F850 /* UIGestureRecognizer+Actions.swift */,
|
1AB88F0524D4D3A90006F850 /* UIGestureRecognizer+Actions.swift */,
|
||||||
);
|
);
|
||||||
@@ -413,6 +419,7 @@
|
|||||||
1A03811224E71EAA00826501 /* GradientView.swift in Sources */,
|
1A03811224E71EAA00826501 /* GradientView.swift in Sources */,
|
||||||
1ADFF4C024CA6964006DC7AE /* URLBar.swift in Sources */,
|
1ADFF4C024CA6964006DC7AE /* URLBar.swift in Sources */,
|
||||||
CD853BD124E778B800D2BDCC /* History.xcdatamodeld in Sources */,
|
CD853BD124E778B800D2BDCC /* History.xcdatamodeld in Sources */,
|
||||||
|
CD7A8919251989C90075991E /* UIKeyCommand+ConvInit.swift in Sources */,
|
||||||
1ADFF4C724CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift in Sources */,
|
1ADFF4C724CA6DEB006DC7AE /* UIEdgeInsets+Layout.swift in Sources */,
|
||||||
1ADFF4AE24C8ED32006DC7AE /* ResourcePolicyManager.swift in Sources */,
|
1ADFF4AE24C8ED32006DC7AE /* ResourcePolicyManager.swift in Sources */,
|
||||||
1ADFF47424C7DE9C006DC7AE /* BrowserViewController.swift in Sources */,
|
1ADFF47424C7DE9C006DC7AE /* BrowserViewController.swift in Sources */,
|
||||||
@@ -429,6 +436,7 @@
|
|||||||
1AB88EFD24D3BA560006F850 /* TabController.swift in Sources */,
|
1AB88EFD24D3BA560006F850 /* TabController.swift in Sources */,
|
||||||
1ADFF4C324CA6AF6006DC7AE /* Geometry.swift in Sources */,
|
1ADFF4C324CA6AF6006DC7AE /* Geometry.swift in Sources */,
|
||||||
1ADFF4C924CA793E006DC7AE /* ToolbarViewController.swift in Sources */,
|
1ADFF4C924CA793E006DC7AE /* ToolbarViewController.swift in Sources */,
|
||||||
|
CD7A89172519872D0075991E /* KeyboardShortcuts.swift in Sources */,
|
||||||
1ADFF4CD24CBB0C8006DC7AE /* ScriptPolicyViewController.swift in Sources */,
|
1ADFF4CD24CBB0C8006DC7AE /* ScriptPolicyViewController.swift in Sources */,
|
||||||
1A14FC2824D26749009B3F83 /* Tab.swift in Sources */,
|
1A14FC2824D26749009B3F83 /* Tab.swift in Sources */,
|
||||||
1ADFF47924C7DFF8006DC7AE /* BrowserView.swift in Sources */,
|
1ADFF47924C7DFF8006DC7AE /* BrowserView.swift in Sources */,
|
||||||
|
|||||||
Reference in New Issue
Block a user