From 91870ca38a5394029694c702ca9b4fd8cadabd17 Mon Sep 17 00:00:00 2001 From: Jarvis Date: Tue, 28 Aug 2018 17:01:42 +0800 Subject: [PATCH] Add hotkey switch proxy mode(reference: ShadowsocksX-NG). --- V2RayX.xcodeproj/project.pbxproj | 45 +++++++ V2RayX/AppDelegate.h | 1 + V2RayX/AppDelegate.m | 46 +++++++ V2RayX/ConfigWindow.xib | 27 ++++- V2RayX/Info.plist | 2 +- V2RayX/MASShortcut.framework/Headers | 1 + V2RayX/MASShortcut.framework/MASShortcut | 1 + V2RayX/MASShortcut.framework/Modules | 1 + V2RayX/MASShortcut.framework/Resources | 1 + .../A/Headers/MASDictionaryTransformer.h | 19 +++ .../Versions/A/Headers/MASKeyCodes.h | 44 +++++++ .../Versions/A/Headers/MASKeyMasks.h | 18 +++ .../Versions/A/Headers/MASShortcut.h | 81 +++++++++++++ .../Versions/A/Headers/MASShortcutBinder.h | 67 +++++++++++ .../Versions/A/Headers/MASShortcutMonitor.h | 27 +++++ .../Versions/A/Headers/MASShortcutValidator.h | 29 +++++ .../A/Headers/MASShortcutView+Bindings.h | 25 ++++ .../Versions/A/Headers/MASShortcutView.h | 26 ++++ .../Versions/A/Headers/Shortcut.h | 8 ++ .../Versions/A/MASShortcut | Bin 0 -> 154320 bytes .../Versions/A/Modules/module.modulemap | 6 + .../Versions/A/Resources/Info.plist | 44 +++++++ .../A/Resources/cs.lproj/Localizable.strings | Bin 0 -> 4158 bytes .../A/Resources/de.lproj/Localizable.strings | Bin 0 -> 4512 bytes .../A/Resources/en.lproj/Localizable.strings | Bin 0 -> 4300 bytes .../A/Resources/es.lproj/Localizable.strings | Bin 0 -> 4406 bytes .../A/Resources/fr.lproj/Localizable.strings | Bin 0 -> 4532 bytes .../A/Resources/it.lproj/Localizable.strings | Bin 0 -> 4662 bytes .../A/Resources/ja.lproj/Localizable.strings | Bin 0 -> 3810 bytes .../A/Resources/ko.lproj/Localizable.strings | Bin 0 -> 3660 bytes .../A/Resources/nl.lproj/Localizable.strings | Bin 0 -> 4452 bytes .../A/Resources/pl.lproj/Localizable.strings | Bin 0 -> 4140 bytes .../A/Resources/pt.lproj/Localizable.strings | Bin 0 -> 4298 bytes .../A/Resources/ru.lproj/Localizable.strings | Bin 0 -> 4446 bytes .../A/Resources/sv.lproj/Localizable.strings | Bin 0 -> 4584 bytes .../zh-Hans.lproj/Localizable.strings | Bin 0 -> 3506 bytes .../zh-Hant.lproj/Localizable.strings | Bin 0 -> 3506 bytes V2RayX/MASShortcut.framework/Versions/Current | 1 + V2RayX/ShortcutsController.h | 15 +++ V2RayX/ShortcutsController.m | 23 ++++ V2RayX/ToastWindowController.h | 16 +++ V2RayX/ToastWindowController.m | 112 ++++++++++++++++++ V2RayX/ToastWindowController.xib | 41 +++++++ 43 files changed, 725 insertions(+), 2 deletions(-) create mode 120000 V2RayX/MASShortcut.framework/Headers create mode 120000 V2RayX/MASShortcut.framework/MASShortcut create mode 120000 V2RayX/MASShortcut.framework/Modules create mode 120000 V2RayX/MASShortcut.framework/Resources create mode 100755 V2RayX/MASShortcut.framework/Versions/A/Headers/MASDictionaryTransformer.h create mode 100755 V2RayX/MASShortcut.framework/Versions/A/Headers/MASKeyCodes.h create mode 100755 V2RayX/MASShortcut.framework/Versions/A/Headers/MASKeyMasks.h create mode 100755 V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcut.h create mode 100755 V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutBinder.h create mode 100755 V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutMonitor.h create mode 100755 V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutValidator.h create mode 100755 V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutView+Bindings.h create mode 100755 V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutView.h create mode 100755 V2RayX/MASShortcut.framework/Versions/A/Headers/Shortcut.h create mode 100755 V2RayX/MASShortcut.framework/Versions/A/MASShortcut create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Modules/module.modulemap create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/Info.plist create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/cs.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/de.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/en.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/es.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/fr.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/it.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/ja.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/ko.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/nl.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/pl.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/pt.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/ru.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/sv.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/zh-Hans.lproj/Localizable.strings create mode 100644 V2RayX/MASShortcut.framework/Versions/A/Resources/zh-Hant.lproj/Localizable.strings create mode 120000 V2RayX/MASShortcut.framework/Versions/Current create mode 100644 V2RayX/ShortcutsController.h create mode 100644 V2RayX/ShortcutsController.m create mode 100644 V2RayX/ToastWindowController.h create mode 100644 V2RayX/ToastWindowController.m create mode 100644 V2RayX/ToastWindowController.xib diff --git a/V2RayX.xcodeproj/project.pbxproj b/V2RayX.xcodeproj/project.pbxproj index 1a0b2f1..135f581 100644 --- a/V2RayX.xcodeproj/project.pbxproj +++ b/V2RayX.xcodeproj/project.pbxproj @@ -7,6 +7,12 @@ objects = { /* Begin PBXBuildFile section */ + 631B81132134EFC100ED6268 /* MASShortcut.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 631B81122134EFC100ED6268 /* MASShortcut.framework */; }; + 631B81142134F0FC00ED6268 /* MASShortcut.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 631B81122134EFC100ED6268 /* MASShortcut.framework */; }; + 631B81152134F0FC00ED6268 /* MASShortcut.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 631B81122134EFC100ED6268 /* MASShortcut.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 631B811A2134F40700ED6268 /* ShortcutsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 631B81192134F40700ED6268 /* ShortcutsController.m */; }; + 631B811E21351CED00ED6268 /* ToastWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 631B811C21351CED00ED6268 /* ToastWindowController.m */; }; + 631B811F21351CED00ED6268 /* ToastWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 631B811D21351CED00ED6268 /* ToastWindowController.xib */; }; 9504C07D1C662C3000352520 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9504C07C1C662C3000352520 /* AppDelegate.m */; }; 9504C0801C662C3000352520 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9504C07F1C662C3000352520 /* main.m */; }; 9504C0821C662C3000352520 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9504C0811C662C3000352520 /* Assets.xcassets */; }; @@ -56,6 +62,17 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 631B81162134F0FC00ED6268 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 631B81152134F0FC00ED6268 /* MASShortcut.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; 9504C0C41C662DB400352520 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -77,6 +94,12 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 631B81122134EFC100ED6268 /* MASShortcut.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MASShortcut.framework; sourceTree = ""; }; + 631B81182134F40700ED6268 /* ShortcutsController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShortcutsController.h; sourceTree = ""; }; + 631B81192134F40700ED6268 /* ShortcutsController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShortcutsController.m; sourceTree = ""; }; + 631B811B21351CED00ED6268 /* ToastWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ToastWindowController.h; sourceTree = ""; }; + 631B811C21351CED00ED6268 /* ToastWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ToastWindowController.m; sourceTree = ""; }; + 631B811D21351CED00ED6268 /* ToastWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ToastWindowController.xib; sourceTree = ""; }; 9504C0781C662C3000352520 /* V2RayX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = V2RayX.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9504C07B1C662C3000352520 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 9504C07C1C662C3000352520 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -144,7 +167,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 631B81132134EFC100ED6268 /* MASShortcut.framework in Frameworks */, 95A143CC1C87FCDC008756B9 /* Cocoa.framework in Frameworks */, + 631B81142134F0FC00ED6268 /* MASShortcut.framework in Frameworks */, 9504C0C11C662D9400352520 /* libz.tbd in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -204,6 +229,11 @@ 9504C0D21C66511B00352520 /* ServerProfile.h */, 9504C0D31C66511B00352520 /* ServerProfile.m */, 9504C0861C662C3000352520 /* Info.plist */, + 631B81182134F40700ED6268 /* ShortcutsController.h */, + 631B81192134F40700ED6268 /* ShortcutsController.m */, + 631B811B21351CED00ED6268 /* ToastWindowController.h */, + 631B811C21351CED00ED6268 /* ToastWindowController.m */, + 631B811D21351CED00ED6268 /* ToastWindowController.xib */, 9504C07E1C662C3000352520 /* Supporting Files */, ); path = V2RayX; @@ -296,6 +326,7 @@ 95FCB2451C688BB20081B6FD /* Frameworks */ = { isa = PBXGroup; children = ( + 631B81122134EFC100ED6268 /* MASShortcut.framework */, 95A143CA1C87FC6E008756B9 /* Cocoa.framework */, 9504C0C01C662D9400352520 /* libz.tbd */, ); @@ -334,6 +365,7 @@ 9DB94D77209D273A0001E9DD /* Run Script */, 953B60541DB3E31D00D40654 /* Run Script */, 9504C0761C662C3000352520 /* Resources */, + 631B81162134F0FC00ED6268 /* Embed Frameworks */, ); buildRules = ( ); @@ -426,6 +458,7 @@ buildActionMask = 2147483647; files = ( 9D5EAC151FDCD70300C14B46 /* geoip.dat in Resources */, + 631B811F21351CED00ED6268 /* ToastWindowController.xib in Resources */, 9D5EAC161FDCD70300C14B46 /* geosite.dat in Resources */, 9D3CEE6F209E070F0077CCFE /* customizedConfigWindow.xib in Resources */, 9D5EAC171FDCD70300C14B46 /* v2ctl in Resources */, @@ -486,6 +519,7 @@ 9577E1BE1C6B065E00093BD3 /* GCDWebServerStreamedResponse.m in Sources */, 9504C0801C662C3000352520 /* main.m in Sources */, 9577E1BB1C6B065E00093BD3 /* GCDWebServerDataResponse.m in Sources */, + 631B811A2134F40700ED6268 /* ShortcutsController.m in Sources */, 9577E1BA1C6B065E00093BD3 /* GCDWebServerURLEncodedFormRequest.m in Sources */, 9577E1B71C6B065E00093BD3 /* GCDWebServerDataRequest.m in Sources */, 9577E1BC1C6B065E00093BD3 /* GCDWebServerErrorResponse.m in Sources */, @@ -497,6 +531,7 @@ 9577E1B61C6B065E00093BD3 /* GCDWebServerResponse.m in Sources */, 9577E1B21C6B065E00093BD3 /* GCDWebServer.m in Sources */, 9504C0D41C66511B00352520 /* ServerProfile.m in Sources */, + 631B811E21351CED00ED6268 /* ToastWindowController.m in Sources */, 9577E1B41C6B065E00093BD3 /* GCDWebServerFunctions.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -643,6 +678,11 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/V2RayX", + "$(PROJECT_DIR)/V2RayX/Dependencies", + ); INFOPLIST_FILE = V2RayX/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = cenmrev.V2RayX; @@ -655,6 +695,11 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/V2RayX", + "$(PROJECT_DIR)/V2RayX/Dependencies", + ); INFOPLIST_FILE = V2RayX/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = cenmrev.V2RayX; diff --git a/V2RayX/AppDelegate.h b/V2RayX/AppDelegate.h index 326cc13..77e6cac 100644 --- a/V2RayX/AppDelegate.h +++ b/V2RayX/AppDelegate.h @@ -27,6 +27,7 @@ int runCommandLine(NSString* launchPath, NSArray* arguments); @interface AppDelegate : NSObject { BOOL proxyState; ProxyMode proxyMode; + ProxyMode lastProxyMode; NSInteger localPort; NSInteger httpPort; BOOL udpSupport; diff --git a/V2RayX/AppDelegate.m b/V2RayX/AppDelegate.m index c96709b..7ee3295 100644 --- a/V2RayX/AppDelegate.m +++ b/V2RayX/AppDelegate.m @@ -11,6 +11,8 @@ #import "ConfigWindowController.h" #import #import "ServerProfile.h" +#import "ShortcutsController.h" +#import "ToastWindowController.h" #define kUseAllServer -10 @@ -23,6 +25,7 @@ @interface AppDelegate () { FSEventStreamRef fsEventStream; NSData* v2rayJSONconfig; + ToastWindowController *tosat; } @end @@ -117,6 +120,10 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // resume the service when mac wakes up [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(configurationDidChange) name:NSWorkspaceDidWakeNotification object:NULL]; + + // Register global hotkey + [ShortcutsController bindShortcuts]; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(hotkeyChangeProxyMode) name:@"NOTIFY_SWITCH_PROXY_MODE_SHORTCUT" object:nil]; } - (void) writeDefaultSettings { @@ -216,6 +223,7 @@ - (IBAction)chooseV2rayRules:(id)sender { [self backupSystemProxy]; } proxyMode = rules; + lastProxyMode = proxyMode; [self configurationDidChange]; } @@ -224,6 +232,7 @@ - (IBAction)choosePacMode:(id)sender { [self backupSystemProxy]; } proxyMode = pac; + lastProxyMode = proxyMode; [self configurationDidChange]; } @@ -231,6 +240,7 @@ - (IBAction)chooseGlobalMode:(id)sender { if(proxyState == true && proxyMode == manual) { [self backupSystemProxy]; } + lastProxyMode = proxyMode; proxyMode = global; [self configurationDidChange]; } @@ -240,9 +250,45 @@ - (IBAction)chooseManualMode:(id)sender { [self restoreSystemProxy]; } proxyMode = manual; + lastProxyMode = proxyMode; [self configurationDidChange]; } +- (void)hotkeyChangeProxyMode { + if (proxyMode == global) { + switch (lastProxyMode) { + case rules: + [self chooseV2rayRules:nil]; + [self makeToast:@"V2rayRules Mode"]; + break; + case pac: + [self choosePacMode:nil]; + [self makeToast:@"Pac Mode"]; + break; + case manual: + [self chooseManualMode:nil]; + [self makeToast:@"Manual Mode"]; + break; + default: + break; + } + } else { + [self chooseGlobalMode:nil]; + [self makeToast:@"Global Mode"]; + } +} + +- (void)makeToast:(NSString *)message { + if (tosat) { + [tosat close]; + } + tosat = [[ToastWindowController alloc] initWithWindowNibName:@"ToastWindowController"]; + tosat.message = message; + [tosat showWindow:self]; + [tosat fadeInHud]; + +} + - (IBAction)showConfigWindow:(id)sender { if (configWindowController) { [configWindowController close]; diff --git a/V2RayX/ConfigWindow.xib b/V2RayX/ConfigWindow.xib index 1c48ba9..8f119bf 100644 --- a/V2RayX/ConfigWindow.xib +++ b/V2RayX/ConfigWindow.xib @@ -29,7 +29,7 @@ - + @@ -557,6 +557,31 @@ Gw + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/V2RayX/Info.plist b/V2RayX/Info.plist index 226fb36..9f027ed 100644 --- a/V2RayX/Info.plist +++ b/V2RayX/Info.plist @@ -21,7 +21,7 @@ CFBundleSignature ???? CFBundleVersion - 296 + 330 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) LSUIElement diff --git a/V2RayX/MASShortcut.framework/Headers b/V2RayX/MASShortcut.framework/Headers new file mode 120000 index 0000000..a177d2a --- /dev/null +++ b/V2RayX/MASShortcut.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/V2RayX/MASShortcut.framework/MASShortcut b/V2RayX/MASShortcut.framework/MASShortcut new file mode 120000 index 0000000..b75eafb --- /dev/null +++ b/V2RayX/MASShortcut.framework/MASShortcut @@ -0,0 +1 @@ +Versions/Current/MASShortcut \ No newline at end of file diff --git a/V2RayX/MASShortcut.framework/Modules b/V2RayX/MASShortcut.framework/Modules new file mode 120000 index 0000000..5736f31 --- /dev/null +++ b/V2RayX/MASShortcut.framework/Modules @@ -0,0 +1 @@ +Versions/Current/Modules \ No newline at end of file diff --git a/V2RayX/MASShortcut.framework/Resources b/V2RayX/MASShortcut.framework/Resources new file mode 120000 index 0000000..953ee36 --- /dev/null +++ b/V2RayX/MASShortcut.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/V2RayX/MASShortcut.framework/Versions/A/Headers/MASDictionaryTransformer.h b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASDictionaryTransformer.h new file mode 100755 index 0000000..6e53fd8 --- /dev/null +++ b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASDictionaryTransformer.h @@ -0,0 +1,19 @@ +extern NSString *const MASDictionaryTransformerName; + +/** + Converts shortcuts for storage in user defaults. + + User defaults can’t stored custom types directly, they have to + be serialized to `NSData` or some other supported type like an + `NSDictionary`. In Cocoa Bindings, the conversion can be done + using value transformers like this one. + + There’s a built-in transformer (`NSKeyedUnarchiveFromDataTransformerName`) + that converts any `NSCoding` types to `NSData`, but with shortcuts + it makes sense to use a dictionary instead – the defaults look better + when inspected with the `defaults` command-line utility and the + format is compatible with an older sortcut library called Shortcut + Recorder. +*/ +@interface MASDictionaryTransformer : NSValueTransformer +@end diff --git a/V2RayX/MASShortcut.framework/Versions/A/Headers/MASKeyCodes.h b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASKeyCodes.h new file mode 100755 index 0000000..4c000b1 --- /dev/null +++ b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASKeyCodes.h @@ -0,0 +1,44 @@ +#import +#import +#import "MASKeyMasks.h" + +// These glyphs are missed in Carbon.h +typedef NS_ENUM(unsigned short, kMASShortcutGlyph) { + kMASShortcutGlyphEject = 0x23CF, + kMASShortcutGlyphClear = 0x2715, + kMASShortcutGlyphDeleteLeft = 0x232B, + kMASShortcutGlyphDeleteRight = 0x2326, + kMASShortcutGlyphLeftArrow = 0x2190, + kMASShortcutGlyphRightArrow = 0x2192, + kMASShortcutGlyphUpArrow = 0x2191, + kMASShortcutGlyphDownArrow = 0x2193, + kMASShortcutGlyphEscape = 0x238B, + kMASShortcutGlyphHelp = 0x003F, + kMASShortcutGlyphPageDown = 0x21DF, + kMASShortcutGlyphPageUp = 0x21DE, + kMASShortcutGlyphTabRight = 0x21E5, + kMASShortcutGlyphReturn = 0x2305, + kMASShortcutGlyphReturnR2L = 0x21A9, + kMASShortcutGlyphPadClear = 0x2327, + kMASShortcutGlyphNorthwestArrow = 0x2196, + kMASShortcutGlyphSoutheastArrow = 0x2198, +}; + +NS_INLINE NSString* NSStringFromMASKeyCode(unsigned short ch) +{ + return [NSString stringWithFormat:@"%C", ch]; +} + +NS_INLINE NSUInteger MASPickCocoaModifiers(NSUInteger flags) +{ + return (flags & (NSEventModifierFlagControl | NSEventModifierFlagShift | NSEventModifierFlagOption | NSEventModifierFlagCommand)); +} + +NS_INLINE UInt32 MASCarbonModifiersFromCocoaModifiers(NSUInteger cocoaFlags) +{ + return + (cocoaFlags & NSEventModifierFlagCommand ? cmdKey : 0) + | (cocoaFlags & NSEventModifierFlagOption ? optionKey : 0) + | (cocoaFlags & NSEventModifierFlagControl ? controlKey : 0) + | (cocoaFlags & NSEventModifierFlagShift ? shiftKey : 0); +} diff --git a/V2RayX/MASShortcut.framework/Versions/A/Headers/MASKeyMasks.h b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASKeyMasks.h new file mode 100755 index 0000000..5813c1d --- /dev/null +++ b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASKeyMasks.h @@ -0,0 +1,18 @@ +#import + +// https://github.com/shpakovski/MASShortcut/issues/99 +// +// Long story short: NSControlKeyMask and friends were replaced with NSEventModifierFlagControl +// and similar in macOS Sierra. The project builds fine & clean, but including MASShortcut in +// a project with deployment target set to 10.12 results in several deprecation warnings because +// of the control masks. Simply replacing the old symbols with the new ones isn’t an option, +// since it breaks the build on older SDKs – in Travis, for example. +// +// It should be safe to remove this whole thing once the 10.12 SDK is ubiquitous. + +#if __MAC_OS_X_VERSION_MAX_ALLOWED < 101200 +#define NSEventModifierFlagCommand NSCommandKeyMask +#define NSEventModifierFlagControl NSControlKeyMask +#define NSEventModifierFlagOption NSAlternateKeyMask +#define NSEventModifierFlagShift NSShiftKeyMask +#endif diff --git a/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcut.h b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcut.h new file mode 100755 index 0000000..8f420e4 --- /dev/null +++ b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcut.h @@ -0,0 +1,81 @@ +#import "MASKeyCodes.h" + +/** + A model class to hold a key combination. + + This class just represents a combination of keys. It does not care if + the combination is valid or can be used as a hotkey, it doesn’t watch + the input system for the shortcut appearance, nor it does access user + defaults. +*/ +@interface MASShortcut : NSObject + +/** + The virtual key code for the keyboard key. + + Hardware independent, same as in `NSEvent`. See `Events.h` in the HIToolbox + framework for a complete list, or Command-click this symbol: `kVK_ANSI_A`. +*/ +@property (nonatomic, readonly) NSUInteger keyCode; + +/** + Cocoa keyboard modifier flags. + + Same as in `NSEvent`: `NSCommandKeyMask`, `NSAlternateKeyMask`, etc. +*/ +@property (nonatomic, readonly) NSUInteger modifierFlags; + +/** + Same as `keyCode`, just a different type. +*/ +@property (nonatomic, readonly) UInt32 carbonKeyCode; + +/** + Carbon modifier flags. + + A bit sum of `cmdKey`, `optionKey`, etc. +*/ +@property (nonatomic, readonly) UInt32 carbonFlags; + +/** + A string representing the “key” part of a shortcut, like the `5` in `⌘5`. + + @warning The value may change depending on the active keyboard layout. + For example for the `^2` keyboard shortcut (`kVK_ANSI_2+NSControlKeyMask` + to be precise) the `keyCodeString` is `2` on the US keyboard, but `ě` when + the Czech keyboard layout is active. See the spec for details. +*/ +@property (nonatomic, readonly) NSString *keyCodeString; + +/** + A key-code string used in key equivalent matching. + + For precise meaning of “key equivalents” see the `keyEquivalent` + property of `NSMenuItem`. Here the string is used to support shortcut + validation (“is the shortcut already taken in this menu?”) and + for display in `NSMenu`. + + The value of this property may differ from `keyCodeString`. For example + the Russian keyboard has a `Г` (Ge) Cyrillic character in place of the + latin `U` key. This means you can create a `^Г` shortcut, but in menus + that’s always displayed as `^U`. So the `keyCodeString` returns `Г` + and `keyCodeStringForKeyEquivalent` returns `U`. +*/ +@property (nonatomic, readonly) NSString *keyCodeStringForKeyEquivalent; + +/** + A string representing the shortcut modifiers, like the `⌘` in `⌘5`. +*/ +@property (nonatomic, readonly) NSString *modifierFlagsString; + +- (instancetype)initWithKeyCode:(NSUInteger)code modifierFlags:(NSUInteger)flags; ++ (instancetype)shortcutWithKeyCode:(NSUInteger)code modifierFlags:(NSUInteger)flags; + +/** + Creates a new shortcut from an `NSEvent` object. + + This is just a convenience initializer that reads the key code and modifiers from an `NSEvent`. +*/ ++ (instancetype)shortcutWithEvent:(NSEvent *)anEvent; + +@end diff --git a/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutBinder.h b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutBinder.h new file mode 100755 index 0000000..e7406de --- /dev/null +++ b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutBinder.h @@ -0,0 +1,67 @@ +#import "MASShortcutMonitor.h" + +/** + Binds actions to user defaults keys. + + If you store shortcuts in user defaults (for example by binding + a `MASShortcutView` to user defaults), you can use this class to + connect an action directly to a user defaults key. If the shortcut + stored under the key changes, the action will get automatically + updated to the new one. + + This class is mostly a wrapper around a `MASShortcutMonitor`. It + watches the changes in user defaults and updates the shortcut monitor + accordingly with the new shortcuts. +*/ +@interface MASShortcutBinder : NSObject + +/** + A convenience shared instance. + + You may use it so that you don’t have to manage an instance by hand, + but it’s perfectly fine to allocate and use a separate instance instead. +*/ ++ (instancetype) sharedBinder; + +/** + The underlying shortcut monitor. +*/ +@property(strong) MASShortcutMonitor *shortcutMonitor; + +/** + Binding options customizing the access to user defaults. + + As an example, you can use `NSValueTransformerNameBindingOption` to customize + the storage format used for the shortcuts. By default the shortcuts are converted + from `NSData` (`NSKeyedUnarchiveFromDataTransformerName`). Note that if the + binder is to work with `MASShortcutView`, both object have to use the same storage + format. +*/ +@property(copy) NSDictionary *bindingOptions; + +/** + Binds given action to a shortcut stored under the given defaults key. + + In other words, no matter what shortcut you store under the given key, + pressing it will always trigger the given action. +*/ +- (void) bindShortcutWithDefaultsKey: (NSString*) defaultsKeyName toAction: (dispatch_block_t) action; + +/** + Disconnect the binding between user defaults and action. + + In other words, the shortcut stored under the given key will no longer trigger an action. +*/ +- (void) breakBindingWithDefaultsKey: (NSString*) defaultsKeyName; + +/** + Register default shortcuts in user defaults. + + This is a convenience frontent to `[NSUserDefaults registerDefaults]`. + The dictionary should contain a map of user defaults’ keys to appropriate + keyboard shortcuts. The shortcuts will be transformed according to + `bindingOptions` and registered using `registerDefaults`. +*/ +- (void) registerDefaultShortcuts: (NSDictionary*) defaultShortcuts; + +@end diff --git a/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutMonitor.h b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutMonitor.h new file mode 100755 index 0000000..dc3d458 --- /dev/null +++ b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutMonitor.h @@ -0,0 +1,27 @@ +#import "MASShortcut.h" + +/** + Executes action when a shortcut is pressed. + + There can only be one instance of this class, otherwise things + will probably not work. (There’s a Carbon event handler inside + and there can only be one Carbon event handler of a given type.) +*/ +@interface MASShortcutMonitor : NSObject + +- (instancetype) init __unavailable; ++ (instancetype) sharedMonitor; + +/** + Register a shortcut along with an action. + + Attempting to insert an already registered shortcut probably won’t work. + It may burn your house or cut your fingers. You have been warned. +*/ +- (BOOL) registerShortcut: (MASShortcut*) shortcut withAction: (dispatch_block_t) action; +- (BOOL) isShortcutRegistered: (MASShortcut*) shortcut; + +- (void) unregisterShortcut: (MASShortcut*) shortcut; +- (void) unregisterAllShortcuts; + +@end diff --git a/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutValidator.h b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutValidator.h new file mode 100755 index 0000000..95fe828 --- /dev/null +++ b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutValidator.h @@ -0,0 +1,29 @@ +#import "MASShortcut.h" + +/** + This class is used by the recording control to tell which shortcuts are acceptable. + + There are two kinds of shortcuts that are not considered acceptable: shortcuts that + are too simple (like single letter keys) and shortcuts that are already used by the + operating system. +*/ +@interface MASShortcutValidator : NSObject + +/** + Set to `YES` if you want to accept Option-something shortcuts. + + `NO` by default, since Option-something shortcuts are often used by system, + for example Option-G will type the © sign. This also applies to Option-Shift + shortcuts – in other words, shortcut recorder will not accept shortcuts like + Option-Shift-K by default. (Again, since Option-Shift-K inserts the Apple + logo sign by default.) +*/ +@property(assign) BOOL allowAnyShortcutWithOptionModifier; + ++ (instancetype) sharedValidator; + +- (BOOL) isShortcutValid: (MASShortcut*) shortcut; +- (BOOL) isShortcut: (MASShortcut*) shortcut alreadyTakenInMenu: (NSMenu*) menu explanation: (NSString**) explanation; +- (BOOL) isShortcutAlreadyTakenBySystem: (MASShortcut*) shortcut explanation: (NSString**) explanation; + +@end diff --git a/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutView+Bindings.h b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutView+Bindings.h new file mode 100755 index 0000000..01b2246 --- /dev/null +++ b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutView+Bindings.h @@ -0,0 +1,25 @@ +#import "MASShortcutView.h" + +/** + A simplified interface to bind the recorder value to user defaults. + + You can bind the `shortcutValue` to user defaults using the standard + `bind:toObject:withKeyPath:options:` call, but since that’s a lot to type + and read, here’s a simpler option. + + Setting the `associatedUserDefaultsKey` binds the view’s shortcut value + to the given user defaults key. You can supply a value transformer to convert + values between user defaults and `MASShortcut`. If you don’t supply + a transformer, the `NSUnarchiveFromDataTransformerName` will be used + automatically. + + Set `associatedUserDefaultsKey` to `nil` to disconnect the binding. +*/ +@interface MASShortcutView (Bindings) + +@property(copy) NSString *associatedUserDefaultsKey; + +- (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformer: (NSValueTransformer*) transformer; +- (void) setAssociatedUserDefaultsKey: (NSString*) newKey withTransformerName: (NSString*) transformerName; + +@end diff --git a/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutView.h b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutView.h new file mode 100755 index 0000000..75d4eb3 --- /dev/null +++ b/V2RayX/MASShortcut.framework/Versions/A/Headers/MASShortcutView.h @@ -0,0 +1,26 @@ +@class MASShortcut, MASShortcutValidator; + +extern NSString *const MASShortcutBinding; + +typedef NS_ENUM(NSInteger, MASShortcutViewStyle) { + MASShortcutViewStyleDefault = 0, // Height = 19 px + MASShortcutViewStyleTexturedRect, // Height = 25 px + MASShortcutViewStyleRounded, // Height = 43 px + MASShortcutViewStyleFlat +}; + +@interface MASShortcutView : NSView + +@property (nonatomic, strong) MASShortcut *shortcutValue; +@property (nonatomic, strong) MASShortcutValidator *shortcutValidator; +@property (nonatomic, getter = isRecording) BOOL recording; +@property (nonatomic, getter = isEnabled) BOOL enabled; +@property (nonatomic, copy) void (^shortcutValueChange)(MASShortcutView *sender); +@property (nonatomic, assign) MASShortcutViewStyle style; + +/// Returns custom class for drawing control. ++ (Class)shortcutCellClass; + +- (void)setAcceptsFirstResponder:(BOOL)value; + +@end diff --git a/V2RayX/MASShortcut.framework/Versions/A/Headers/Shortcut.h b/V2RayX/MASShortcut.framework/Versions/A/Headers/Shortcut.h new file mode 100755 index 0000000..5a8de8e --- /dev/null +++ b/V2RayX/MASShortcut.framework/Versions/A/Headers/Shortcut.h @@ -0,0 +1,8 @@ +#import "MASKeyMasks.h" +#import "MASShortcut.h" +#import "MASShortcutValidator.h" +#import "MASShortcutMonitor.h" +#import "MASShortcutBinder.h" +#import "MASDictionaryTransformer.h" +#import "MASShortcutView.h" +#import "MASShortcutView+Bindings.h" diff --git a/V2RayX/MASShortcut.framework/Versions/A/MASShortcut b/V2RayX/MASShortcut.framework/Versions/A/MASShortcut new file mode 100755 index 0000000000000000000000000000000000000000..9d28d855df9b86cf2777add44f299882a7f5efb9 GIT binary patch literal 154320 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 + + + + BuildMachineOSBuild + 17G65 + CFBundleDevelopmentRegion + English + CFBundleExecutable + MASShortcut + CFBundleIdentifier + com.github.shpakovski.MASShortcut + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + MASShortcut + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.3.6 + CFBundleSupportedPlatforms + + MacOSX + + CFBundleVersion + 2.3.6 + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 9F2000 + DTPlatformVersion + GM + DTSDKBuild + 17E189 + DTSDKName + macosx10.13 + DTXcode + 0941 + DTXcodeBuild + 9F2000 + NSHumanReadableCopyright + Copyright © Vadim Shpakovski. All rights reserved. + + diff --git a/V2RayX/MASShortcut.framework/Versions/A/Resources/cs.lproj/Localizable.strings b/V2RayX/MASShortcut.framework/Versions/A/Resources/cs.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..bd25e519dc834da7857f7c42079f5e6f0d2efbb5 GIT binary patch literal 4158 zcmcJSO>YxH42In+5_b@nRV5H0D0dJN2sogKwju!u#AVxrCNxc|Y*J_s{MQ^gf6Uwb^ie?7AMme~u-ZDhOFv!R}H{hHdq##+m4$7Xt(o<0r2 z+C-AOTA5f^awFT5Tp^iU-=2Qow?}r()+>6~wfpXgUA@Yc3v%%nF3q&s)9-|Q%UZG*8S77F zroLK%iC#0XV-g}vjh$63Z-pUNRc7rPzZ05G;f8zj|H#v0*{*BOWR<+Zv1$}9l1!M& ze9wb_&ZT*%lxmeX*>g53asm@0kDF**VmS(`)FTZ`d8#65YTQ#Kj@4uOvWxtI_N6}5 zwrzW^uJ%f6&h0X~L&;MU3C|lno#;D}u7!3~t#`!6STV8F!A#`w`!aak3AK>W!mk5W zB%GwqW0${e&t!2|Ya@Ne!Tyerq}oVcwJJLBI5Xc*KD?uL#m-D|q#J%;TS#BkcOp~h zlk4nY&t?0+6Y4tl%R*1^fb%0|jM#WTSQeG@;=y@Cz2>LggWf{cF6uCj%xff}dZ=s< z)Pab_#a(m5J}FDD6}3#B`HAEGY#8_pcgQ4o{LJ$X=O>6GjQl;@_XpZ}Ak9Rr*+=Q2 z9vhDWPyJw#Y|=-)=f(K9v|2p}?nvfMK<=EOb~xwgjlQ>C$=P=3O`j!!pFXP;wo$6J zjx@Nh&0e&emH2rmoiKhZrXmSrGo9-L{T?gJu#`E+`?lxohoa+IXz3lk#aw#d;O|2F zr_z0-{Y((pI0^5M86sIeeS6{qav+OU^+7n&Md^Oe41T#HO3B}Dy|SJ&ciglU0tn37ShX^;k;747u?9`TsO0;WfHlI zy^vgyd1oC}7E#>|UG!cfJI(X5S&^CIN%b%_r)W2)T`Vt~c;P3LK$@0ge=N^eNKva) zxkr{si<$f|a5P5yJS$}0BjBe1%r4KUUdL%Faf_K`z6l+yr+)UNqt2sp9=F9Xrf-l^ z1)NlIQZG+X%jb4{b!&w*jY92`OYk{H&hOl=hZAmJs~{!9bM50K?}lB}Jw1XO0oIx~ zgbnR#2fy4BHyXcbRHt|JFj>*5+!ydMH**tN$Va+PxdS$ZQ=Rs7Y-VfD#-b<~%K_C?4z%p1zD^KRC00)ihGXJ@s1 lyb~LV>y}VZ4a@y|FOG7r@Ds&%asH@#t#PKn=f&wP_Xl;F+K&JL literal 0 HcmV?d00001 diff --git a/V2RayX/MASShortcut.framework/Versions/A/Resources/de.lproj/Localizable.strings b/V2RayX/MASShortcut.framework/Versions/A/Resources/de.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..ed230e075f1d29d8cc65967afb46fe982a67b14c GIT binary patch literal 4512 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 literal 0 HcmV?d00001 diff --git a/V2RayX/MASShortcut.framework/Versions/A/Resources/fr.lproj/Localizable.strings b/V2RayX/MASShortcut.framework/Versions/A/Resources/fr.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..cab002e5c411622f778bb99b8ad632f5daba4b3b GIT binary patch literal 4532 zcmchb%Tkj;5QTf~6Ugo_s&qk#?zOCvLKYSx6hT*RLI@BE0drCDm3#zW#-;Hg)bmYe zocS*#p+t*9Gn1K~?$f8w^ziHFBU`h=Hmz*~>sZ(N8nyLlY(2ZsTw#Yc(P%sy^}^gx zD?6GQ+L6``>_qEETGQ5VSD)AHk=?P?lHFC!Kh^K5ZD_|pR{L5z)cA?k-q8*`Igr&0 zeZ%>e8Xt#K3a!VRb?rFU{MfGa-N;VEw`2K&k5ylj7kydl*qK%kN1;=b|Jd%@#|C@J z<4t+gv-disYoE39QdTCiQfNE~)=u<22w<6cV&fdJ1SwW`v}U#ptEhuKbYIi4XBJvq~NSK`)1 zi04R=T<=XC#X=|awey24*EzHi&Kfr0_c5RbtE;CKvNY0sTYJf2Tg--I6U}z@IdOW| zww1-mWgq1X-ns!py_(43P`fz0xsLYbL#(&LS{2?WZ?^u5jrH6;mOs_g9DCmzWOl9rHVP#*#kvK z)g<+5*`94k4YxGs%+Ec%3}|#SR&5E5G@G;QAgiUQjqrvlAnw~>_`ytDqNkv7u3Cky zD15vb?%6Y)*wGw%ele>z;*M35P=2XZtj#S^ael|RCDaXV?P@=<{LsJDBK9~H4IU{M zAeCdXqnVL@+R7HIZyT4xpafBIM;f8@+(aphVCD)^jxnJ%4<~LeD!e^I4mARSMVjQE zfo$&8x>(SYW`V_GoqcF;mAw~2tx#m#RDM6gDmV?N$T0r+?djQN6l0#xln2^*F3X@+ zS6)=tv2hd_orV+1Cd%t78S&rNZ29K6uQfZtb7~s~;ji~HzPDA%*t(?!qS;rSdCc$Gk=)J^p9CknH3OI${Vx_=m?;NlOT4)bZ4RzPSe0Ig& zVRL|smF{}HNvp}_RCcENKjo5J%d0fT z{(luC-abhcM&dNLeCk#IogTzW;SQqDb~SOmx?7;ND@B#RjwoE;==90F-}heEycfa5bq8#gI|)nN z74-gtpia4^c1Vm)}ysKKR3;SK7gwwc3fMj;kef;R4!D)ivK0io!^L_m+LCZtA8q1OoI-hh@Pw8+zcK^ literal 0 HcmV?d00001 diff --git a/V2RayX/MASShortcut.framework/Versions/A/Resources/it.lproj/Localizable.strings b/V2RayX/MASShortcut.framework/Versions/A/Resources/it.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..74b652841ec611257f3e907723c65b4649d9d66b GIT binary patch literal 4662 zcmd6r&2Ljz5XEQBU(oKZB9#T=V_$?s6j&exq;<-Q&5JRyg%hW?6B_>7F1zlIP22Ok z~n8t43TJ-^GRB+UoSJ?(y~@ugkq-NMHC?NV64*u`2QN#PrfT55P_gVgKNAqw~1d z78-A~me@Bs3HDuRbfn+KidXhr(F~URQ_bzCJ8;+Yj9AXKinIGO>{nrkOiVWDWJE#3 zyqc$98o!@~qkBpc0yyNkQF~<5%!2Q_sLtj6Q+Z*bziu?w+0~DZI1%yS{5mS1u^A0m z&NCXJRxM?2Gws;mml zgf-+Gwto$NAFUK7khT?#ob!tDlRegnXeBy7TV)$|N6r+Be$m)SvBjUP>DS0)z9-eD z&he-V=<$X9t#|B2G+m`R4{hqk>BVYZqnxPY@wGg5oE0Jzd7&pPq;{3~;!RhUw$;Ut zH+c~KBJ-P-Pf;o2yh*DZnd^5!bx-`5NXziWW-Y#NZxq*Os?AB3&4j?~Al`%Ru#MP* z$Lp=f-D{L1yqQCHwbHYmJr*5RLyg@x?ggI4`9z|L{uH;8?|KP7c-KKK zJjr%b89j0+98rY7VCHw9-5zPLB`6i>+Ij)2yhn>pHdx^d@hA7nk>=K&279$xRpaS0 z=wqJU@7cDpe`~FZs#x@>n{SbA{aXJ2lqhnPx=6R|I_66GLqhd`Oy6&w`3)wC?K5eR zbC3$<)_l^h+J?FpT<=}hbuKB>VKn!k5~cO~3pooj`|dDg4&7O~|3uZP?{&;V0ntv6 z2%RvuEbcimcJnEbk7PPEIPx*>7G4QTr|2h=HGiy>1?BadWV`pTruV{FK4_zRU2DA4Ylhq!fQ|0E@k053JInS%$izD#5<~MQQ zslI7)5_j>yyGiAVM5s3Pc$8~a&BK>MvFp9sDET=rm+6{|E@&mj?!+9%5HJ^E%P+#CO*x1 Ue!Ydv42E%Q=l>q4Ms(5t0Y@7xzW@LL literal 0 HcmV?d00001 diff --git a/V2RayX/MASShortcut.framework/Versions/A/Resources/ja.lproj/Localizable.strings b/V2RayX/MASShortcut.framework/Versions/A/Resources/ja.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..eaef0b7fc4da9363530368a56a1ee301cd16e464 GIT binary patch literal 3810 zcmcgvO-NKx7`?Wt(0%P5LJ^VrEm{>pk}mS6QD@9Vp`JS9h&m%PW9BBQR{cO=(4zKj zLTne(qD2r!xM&*^{Swr&mQkH^uh%>8K1XNh2N{`n=id9B`+et}`@LU3Thw6{s8cFb zIW?-%Y6?#wzLnI3%3~~0BWe~;rH!WvJyyWXQH&JS80O{FIOY{GC&VX>?}t^3+N&BP z`!-_y1U`*wNj}Ioc_LqBP;N@2I*z$}v4Tia*fkFnj6Z|tjE)i@2GKNO_i2om)I5GG zs;vIC1T4hpV|6H|u-mAb#0;Jz0B(n$d#Bah7W+BG%ko8@$+8ScMjp#&`5~+F5F@Ly zDCyq&ebt>It8*2{$@n2K5nUGFt39nfUmMm;;bU^|XT_buN8Zslb~lRrEV9E)rBy;* z#D9Zn0y}emSJz2A&4U?vjeBg{+$|wn>-fCzG8c{9sv{H-$*<#$5n^MuS%Rx z@v0m{On=7!(O4xiDSG;yW>&(|C1gmy+>*;+{&`QS)uLi8SXIl`I2tpfGK!`f_l7E= zi0?LzEX>0rvWS^OHl`8Z`AAars8;w=JH`x)%aP4sKH2ZEtjKF{cf~t<3e2;bunt8g zP%%8~-{5R&!wW1*a%mcxBmd~L)}IfklZZHqu^j&LI{t`0v(s?J8L)gD&jAM%a>>JZ=H8UYt}kn5l_5H=<}{J%!ScGz>++zVwmInfJ`!IXtDY?SR5s$f>Ox4U?U=VK4 zfFoErjh&gbxJS|-O>RsU_>|QVSxtJR@iUwMPK-vK{UGLaYvj~v0A&%c=@iV`WTa+2 z+J7>bK_4<*MNu`EX(}l>kAZoq!^ny}m$#DbO(w==A#rGyn$JiZdW5J)=HNwFu!5{* z2a%Mlbcy5dE@95E!n5L$7WK|_vo<+;Zg;9q>Ng`lDqTCrJsW_pUfjLafLQhNMjikm ze|sfs=v_MHy1Y*t?Nma#D0>FKXV^6)+o>0uwR7>`U7Hc#GKXJ<1BdD(mtTJ^LbhVA}~(vGGorddxyEkJ1BRdvr#ZR;;xje+*Vp5wmIfE5^Q}DYE zcf&@JZ}oOid#_nL&OgC-O0%+>cR}0vRQGOHTh9BzW~v|o9Z?~bPxLYA^UQd>Vaade CiX`&@ literal 0 HcmV?d00001 diff --git a/V2RayX/MASShortcut.framework/Versions/A/Resources/ko.lproj/Localizable.strings b/V2RayX/MASShortcut.framework/Versions/A/Resources/ko.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..897047d0f3e050850a5f0c838eb4a075aac6fee1 GIT binary patch literal 3660 zcmcInzi(4l6g~qJ6GJPdQiiK2AV4KBR&9|$gaJ_qA^~~uz)LXLBC(_R0gcqLm5|B^ z5`Tafq=3LOkbsdKOa3tw$$;D`0|Ns~w+eM?`+fK1a{b zpAX7m*)3y{bH}iL6z?(l@ap#ZnEU{X-LRwo8JtysZ+czC^A&rx!O6sM2xl%}J(Oj9 zSCp*%HUt79izD>D=W*JcT!RJC8=&>5d3Hu__Bqev3_B0j!mg1I<-4zplsdnx8TqZX zcXcrAS(}+8KKc!Sg{ZRlJZO|Iu1V~f$6GTU&xS`&)TNG*2er|56!Ar5gPF<5l-$5y z#gfB`Jl9w68lIL>|ANJPdD~o-I)7I;Dw?ZOC+hFGJ$DJ`$7^-dW`Hb<$6NTryRF_Z%;O&-cJs}9c4FJw}f5v-JjRzfx+?L$aIX69*wI( zk~PU1d=FpolMKADCge*r>YXg(7~}|fu)h+`&7dflb5_rBFzH<_l3vHxzfO2f?!JmB zm(k%__{byL1^DwSFfHfgIJD#>)|8XINETsFE_>gl`n|Vdt5i4gRW%y#3|Qq@?lgu~ zW)CpF&%wu;&8~Jx$&&?i5xGTubh^4%j=|#`*7A52tp8aXx8t~vNNtr(=~W}l>Ln=C z2x4qDp48jr_vL7$XK+#xuK?QIo6FA??X2xar(i`qQU9sazBbH+cJWp@*e-f%1-mTR z?0G5zYqXOtD6#;Sy{HbMwmIkqbFs6oO-LFwIfZ-3AhH4w=qb0!w`k2& z(-qiw>J zrz15xXBFlOET}X(3lwFdr>nx2kw+`J?lJt|sF&*L*G6`=D}Qtvqw7XiYWJH)etPoV zi%!Gc0*pe+-lt^I~?>-tG--Gb^oew)W@5Qs(1SM(!JtT)AvIW)#M%HXP7V7 z363Mw)VyUf`$#)=#86qjG4VQUWtc%{ff?<2i08>h*h;@yM1eLroA zXFPfDBzwSE9i6xHpwD1(j$@~9HOrAHyg~gO=oG1Us-+dXgMFph;zYt}a}jxRYukHa zHQ8nC9_p^KTI1(5RSAEat49OtpRJeZ)B<)n)&* zYw6VrI#R!r%^o^X;Y~3CbbFqraer_oFyc9%epO;4F4xAXqAiulZv@+N)qT%v< c0emITr_d?vfvqDMZ{B-0`f18{%B{TkA6XkJoB#j- literal 0 HcmV?d00001 diff --git a/V2RayX/MASShortcut.framework/Versions/A/Resources/nl.lproj/Localizable.strings b/V2RayX/MASShortcut.framework/Versions/A/Resources/nl.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..183efeb39fd52fbdce7d3af095f471c12c7901cb GIT binary patch literal 4452 zcmcJTO-~d-5Qh8AFVNeBL=QyZt}&4SF^0erK~7!r5m_2*L62~EA?yQu3V+H!kxOQ-X`~NSAK0I$uq5t z+_~fi?ox7N$&`A!`n~2h-HKbS>0QDN@dv3%?`fxXiEMDK<75U29}hhOLHMXm1n{kdfzE`f|4vM(yd~#eb3L9B zNAB7BnOk1>NM|%TF!TN)R!u934G}7}mzb2Y5LQjK+STufwBz=~(!gMQOF6r{1Sc(r zh}KBEI2&Yn_IwqFkY$BCYA`*bIcnitr3`@~w|bgP%cJvN2%7o}oee+WSlt(oNzO-R zd`S6p-pKz&@ew1U9T=VCGKu+ket9iqLDNsUzDs%JPM+=Q)PX#McVm4za))k9HE&mI z#_SZ^Q1WC%iiS1vg4L8w$4Rb)>IYBABrJXoMjzi-jer!U-6|Jhr=ha?|HggNiDz0H z=&$nUpL)APmPCuFDQ(pO-{$&}?R&kUikfZKSJ+divvhr@mZ?JhuVcNDr({)(EPk{ql3QpVoaZ}g61*BmMmUU;l78M0E6DXMib|l$qeQDaQ65)naz&YuSY)tOJveW4DpyBn+k^ zfTfuaPvL9oLwIs6%`<6ca>6H8{hKT=^pzQiUK{3&7-#rr)025A?~E4NEkzL@UweD# z-SaGig*}f64l%(rvyY4CmOGB_1Z$L;H1H;@6 zGr5Zlr8lh2KgIHTD9%{-BHPnh+-hx{zU)LQ!B3$hH!Lf1Kcunm$jhOx&bys3DS{jH zabm>Ib0G{j9%Nz#=}VG*NQK-am(zN+*u4l1mG3~!)ABhHNo=BH;)U`)5+HBmx7n2I zX{#Ft(!K26(mD)Lq*sL6_0V1T_#a0Ov;zh<=gT-p!FluMfnptRmu-_iDC#wES6*85 ze*9D$7Qwz4+HD`jMgH$0Ou}&Q@mMWq**7r=9(7a!m^>b~@3Z9SzBZAvW9l=5J>*Y% I_a`oY0j?VZ#Q*>R literal 0 HcmV?d00001 diff --git a/V2RayX/MASShortcut.framework/Versions/A/Resources/pl.lproj/Localizable.strings b/V2RayX/MASShortcut.framework/Versions/A/Resources/pl.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..f4226e11cf4fff03764b301f6f668c85bc9d2963 GIT binary patch literal 4140 zcmcJSOK)38427vhP$0jc-VF@2i=avNDGJm`vM7w$K`l3nb|cHO^|B=BQB{Wjb@pw~ zH`HYA%a#NrFl6YCIOHLD__+W5``TVuu(#H+iFK`KV?A~BZD|9W>MYomt@O0qJ`Lj8 zT#{X#%-FG@)+D5-EtRH_}3JD0SNHd19v~_JH3A_kGozbJaXX^%i8SkkO z4Rn8^|3mvJS^~jp>+@RY-?bd&dW&r&E1zX=KmYpDFlq1sY#nI=d0*f6jYRVOo$ieF z@vKxMmOZ?bCo6j=9~Sbn3Hcw298v7qx&5vGj%gsx=+7A+>1iX*Oe5}V{qnfgY%9p> zST~5|!tQmOIF@5~5-rUeqO^{&fvZ(pA?kzCV<9G%*D*h2uBY!A_qmiAt4QWXWesPH+XxzydY*fdvU4$06PNmsQ7StMhysvLn`k{Qp% z7mj!htYT#xwW!N-&g!gb#zZ!#;KbWH7MFM&1JQ*&^oc5py0%-zV53gbm(7W8-pPLM zHW&8MPSm^J>&*FFL^hK=bx_3OXG8r`_P;GesX|gOgAddX{(cSSwzr)jA%#(Qsz6vs zKTdu82m4hPyE>cbZyN1iMZZ%uWRK2ti-_Dw?xBSqGX2on#6CAFS?H=K4)lAug6WS~ zEXU)6v@Z15(Znc5{ArB=xmu@pWXq!4|JrXP~=ZL$`QM?_b?HP-4C8py=2OJAakyn zJ!B|bX7*ik}PttmQ2F00LVsp+}sBgTWdTi^( zFE)g{F{f@>d=Eeh52$&MI6Z;5%!DAFJ#7U>cs=<{2+~&ER=rm8w&E6pWd4Z}WU{3< zk21fC`8|ob+izFLE6*@JgWho~-lm%0C@y4fBpLVLcL%z~QEMhF&YJZ$!_+%-w)#fk z+bA2d-$(18nz6iFRHtY;CRp`3LSKhB&swk&RLiaXq0YL>Ly^(t`ahH9L*J#mH`9aD zzM5lS-)q}ncyOj0)I@ay%bUih9nmUdKYR;69P@rybH6Afd>iXxpEv2W55ke%`8X^C gmtq8Uc&Kz^?Af#{D=*EhS9 zIhP*VCJ=IHXF6x^HG8kU_RPP(yKc)RZqKD|yntt0_J^9ExjX%qxt{-ZCN!Wdqm4KQvetH2TER{dd5t^3cE{Z=uxFS-%=_Qv zgWXNE h7`{wh;j}vc~2&7sKuGRL{^AW6K2NQlk-1B}{i$K`(zTO$=v5b@>6|>Rs z`{~Yo)#LxF9TCHhJJF6ib7Xzl$4kull}2}B&DdK!*Dv+H^WGA12|M6z%Vw%^Iff1I zYpONnOyBw#!Pm04M5r^(lNGX#UAS|t*^a(PISVYcQJ$FxYcS91gp5t~7QPo( z$Y;M>tE9v=OMH%KKFUsHT0;?7%(7~h-pX^?ZsH?s{3^y^*~*A0k0H_i`aU}4jID}? zT#(hk-YO1TQRg4-T=+`rFW^npT33kg#QdIojugwG-j7<-bf>PNsz1=2@i~u-`lk*e zmIHB#+4~A(Tf!77Bq$k~qkh=$WAL^$*N1=C+ZAdhX$jr2G6{?Gir zLoLJ|HT=rFoqP97?^LUl+Io>-`(;8bZPi3;t)9snDuxegFD>cfk$%toZ(Wb&v7>b6 zt37CFrV*WrE)sJ}1WhICV)szg&>}P|oofn;LvEMpjv=Fu_f0YX zB<+KB=Ex(5Db`)-eJG~A+brblRBWQwVO2*vqY^W>Q>sSv5iE-syb4Fbfhvcd z4<0ODx}W<0TTkS3Sj!x&Dt0xLW-NwS51^+JMIvu3Oog2sHZ)JCpjxN;k2h9Z?}~cQ zxLRFU#~xjR8ng3~MUyC6JX`vVy%qbZx1W#cA0Jcvp$jI zL;cwesmQK;c29+K(Vb$EqR_i<^u!nhm0};JE2uFY-ny~XWM3#OqjpybcFK&hE)sWa z=LcgRr<`zC;JaZCr$4)|EW#Y45mchgoMYi#_kL&nA7HV;+C4vJ+>t>zK{ literal 0 HcmV?d00001 diff --git a/V2RayX/MASShortcut.framework/Versions/A/Resources/ru.lproj/Localizable.strings b/V2RayX/MASShortcut.framework/Versions/A/Resources/ru.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..8869dd36d502c41f9cd66b4b5bd79c6e2b38525f GIT binary patch literal 4446 zcmchb-A`Lb5XI-=KIJh|r8ZL9Emc}6Y7*i?AUHPIu0`PSdSgJVA14Z`n7n_v{<7r_0mh^Fw=LcWh%ovT@e)h`QL+V}n} zTO*WRkjsWXpBME>^uo`)bH)?mQ}kW3^}B2h#8nVCvsYN~6IShD%Wl@n4hj~v3O4(_sS$wZxe|w4S40WWuzT_?GzPW;a1w*VfXNQHHPiXFv zW$R>O^Tu3UFCZ;PY770v(;b=>Ipy7?C+6);xV|k^MKOMG&p6}62lao6Q;|~4W44#^ zg&oV_5<6{pj#5>Zv6Xea$6MF%Qy(M)ymk(%#9@c_+8Quo8(FA;Jl+fTt8x;;Z>YO^ z_7vUKf>(~n*jQ7MA(cU@IC<6QkMnyvd}ZJm6cm$mYM z@?E=M&`q7~j^C_%b`cXkqe6<6(L&awR#Y<;uSb=mNklVLh@7)8kg02H&mOBG{s;{9r4wU*7tiPhxzZuVif^bDs+IVL9Ig>J)r7M=&iuWgJg<~F z#QBbO=I;$D66JYcOgU}lmqnU+(tRN^dj1xqU1AsUQt-OwO5I8>@OPBW)}pKsONo8d zx18tdG@%EUP4idK=-B;-?+EI^@!mC=WBC~W;63})GeUlziPOEJQQ=vnR%Nx$$lrv- z9xdXw<>R_d-DwqANb~5Lzeniw*_w3r=9s^VI^IylleZE{^hV&%U|pOdqh)Joe|{rN z&1R$`XB<$!%icUgzfol4Gxwy?fUG#2dAZuPWSKK0|+Of#=E zGP7&V8{3WM%{8acr=#zC_SAN4w_|J}VnLC;fj&s?Z2m{`y zdhSLaK_0-eFWV!HFSHVWz4&$^Bp|FK%@~HVc4Y(2Ac`Q*89lZ;_H~85jQ3cG+(Myw zUHd5uWQnY}wHv)Bek{-Q2CHBkED`c|q#v?;t?%uk?#b#n`l!|b#6`rgP!7mbR>*!|A3SG<4D@s-HcVnf*Lt%V z4_pJsBCdgd^OlGXqvx4c)|v7(W|7$HzC)}lwI0UW7V<}3Z#A={?>UZBJ62T_!~Lnu z?AKc`*L#eb&LU^%$yMF;Q5aGe20N?uLq@~ACPV+Wj?aXq?kflfb%mAHyxcc4qdZ>n ztllf$VPj>W(5KotO_r@jN42PX>VPIHpV0=*trTb~B;RFmAtt*1RdF@#-zYzKTGtbb zu_74>QP#IJ`(TGs%hww7jwoZDYCfHm(Ot+h`iZ76US`^Psmqdn!e4rj9Q+HmpD%SM zVTFYwbtJh!7t`MH$X?3hmBz;UnMD7WG4j+wIVRL5cek^kZqXIUtq$URIutb^o2>t$ zx}dR5uDsWrd1Mg^l5_vBa&sA#At~})PxLH1R<0#^W2Yb|t24GKSLhZUUo7>9*r}*n zT(41%j9saWYF|v~D^uj+eic5j&&umN?S4U#O@zSv60a~DUXg$B_%7=e<|)OznJrJW zawN-St*OMGGdy?}$Y3veq?#zPt7gjou|})=%45xWACc4RLA{7IKk@k5vr5fAL@n!T z2Abxlqq!ZFx{!SoJUwxa{cRIx?`JFfYge)3ZywnZVs-G~s_N16JF%Rsq`8iTGg$5- z-@7;Mkq5GH8aa9$YwCOTKsD_zciJFt{aEFChh=;z16A*B^5OjJ%0Au6`mpp%j5m5F zv)peL72ggmHUxuqO{V40gTx??B z&!^h|rwFN6*h9v#`sj%()`Nh`J`7F1qwwobfxK~^uGi&tOsDTRF})BIS?lL+M|~%6 z+!tU&+IyH)#$T>z^Tg298af(X;0BT_)Vw+PIe+!-0X5@Hly4qM1m*oGk+7O zPPBsiZvBj!Phw}K44)_~L3bP1BvjrSTUXMp8&@tBS4sszH-g|!mqp__GZ`oEy);drN=bQda%b+j_nv#^ru6%O=nzu$ z2uI{ZQn(_6HwRBsVoc<*CdG)D#@kf+ZA`6A!ZL}KNs)qGPK?5?02>D%7tbByfM^zN zo^#uthykAsjOPov$oj5a#^(irn?+PNVzMTRB zBJ(4(zB4#2DaK(z^b%+-YM$+inJVX5oG&LU?)TxDWO%7Q)M=HIAToM% zfP#3^c&;}-6VY+($>5`N?9YS6E&EfCs^LA2EHERkh>9ZqYb0YhkEhzIjpJ<=bvEz2wrD<+XOq}P&()dS4+MtsQp9~6v{=ZNYWWD}z6+lG=ScWqEyxmY#OqmF1ls$L z^P6+2N8Y^Di-Fl@-3;%7zO_Zr=c~osyw_)N?}RsXIvY>z(l!&4MuV!i=H8$sDeg4_lRTgn8aER zfBAAhFk-`M8%q-u=JnjRM62Ykko@Al&&)^Lr@a~NMH~hEIZ)lo%xzSJBdX_&LKW~v zWv2q$N-%oet82wwD`F}FyU8i%fPK%ptk?Y-nFGs8RGp~j7}SBeSYNrqVhD9Oi5o^D zvOEyzdx6;_FUbzpig@&`q3fhITO+Jp^ZnSF#mUTCP~)g?IyX8Cd`l~jtR^*1E0W3o zDXe<6crR>v6>@f=L?;oizPa_@xTj`)N=q)nf|{al`GN>n^iX`bx8HEjaIU5F<#bo% z*0~?&-_5m84@HZy50TZYpXbuCV?$bDHXURpZw@{keSTs0%tG<`_6JC!!LJ#H}2>e(PXxzG!S2nrN*0* zFCMm(4qe)w2rs#@W!HYcV`TI7rev$6Y8gD?rI6(0#*RCCuKkR$_SY!_9yU4?Yh7R- z%nV~A3r_8czgdo82WMpeEpG2D9a*)Br|~JQaeTFLRYTRISXIw29Wy!9_Zy_K3=e>f UWN{SLC&Sl{W98nncx4=a0DOYIY5)KL literal 0 HcmV?d00001 diff --git a/V2RayX/MASShortcut.framework/Versions/A/Resources/zh-Hant.lproj/Localizable.strings b/V2RayX/MASShortcut.framework/Versions/A/Resources/zh-Hant.lproj/Localizable.strings new file mode 100644 index 0000000000000000000000000000000000000000..2bdb7140f2eeef2fad242409362a782d43ad2b4e GIT binary patch literal 3506 zcmcgvO>0v@6dlBh)ovAq2FHS0icwcC`~Zu(5NXmjty)^q*CcI9^U*eaX)6Z5y3pbx z8c-3@tt)ZuPY_(V(4{CS2<~(#8qb-@IC<}-X#!PB%6pSLbI-l^+%q?o-v>pHkm96p zL{`K_Ql#%&UqH+ho_6BFOeN98_O?~-!3i0-EwoNQz|DxWc26& z1@WZt+-!U%qEpzD#z*Jap9hP(XE5=g9^P}v0yB~nQBlBujbsYv@l;#2X}m3=?m2}v z(J)7D`E#M3uU>WL9M1OFXF@Fxwg{u*EO=!2R2=cv z<#Y>d(R?P)=CF&N>oa)}2n^$;i1|2Zv5+nG@)6Aa5qR>SBjJO!AWOUvuVrZwXz$-I zwq+9!ym@IB1GCM#8QukbYm1=I@XF&+ug~D#Nkq7WZcf2N7LjJ)&31fD^ow5T#%Zi+ z9@gTRfj#+aJzu$UEEVia%W0z|tSlMNxYmP#L)8v87|D$cdWL+W3L5p?BTm3$9BWzp z<*NO_hz+Z4EbUO3Q^n0goszpka`)`J^tEWW>&<8%;>hFAf$G*~ZoMKLS3PGGDvviR zI~CYgg3;?ZRI*3#!!bdxM3tB z%K?GD7nnWrlI&ouh)3TVx=vcNHNwU<-;bRcoXo5RHIDkGbEC7sx0Le8YEt90BANW3 z#j00}_rj)6A!ip#bQ1CEn_KUVd1}_Lv}6Jn)D(To=f#1V9xAwfgNA#Ca~+kB=U&a+ z8vTB;TZMVV_IQ09AYMKjy#!setFlza^c5ia&>2EYri?Gqq1-0 zYiZM&7|28Y1h2;3dYm?!~n|tAv4Tt`3 z4;baMJkO&_yd&(?@$VRJYENa%Du%K@bO-KG+OSjl>!)iHtR8E(Sb8zs_QZR3;W^)vrt=OZh%~$LX-g0&}Gg?wRY0`?kW=H6JaAM#DID<@>wZ>jp zFZKs{PsNlP)P4fq5`9 zjEyWfwGaKxas)d#Bl~Z0duQp$>P + +@interface ShortcutsController : NSObject + ++ (void)bindShortcuts; + +@end diff --git a/V2RayX/ShortcutsController.m b/V2RayX/ShortcutsController.m new file mode 100644 index 0000000..e4f4974 --- /dev/null +++ b/V2RayX/ShortcutsController.m @@ -0,0 +1,23 @@ +// +// ShortcutsController.m +// V2RayX +// +// Created by Jarvis on 2018/8/28. +// Copyright © 2018年 Project V2Ray. All rights reserved. +// + +#import "ShortcutsController.h" +#import + +@implementation ShortcutsController + ++ (void)bindShortcuts { + MASShortcutBinder* binder = [MASShortcutBinder sharedBinder]; + [binder + bindShortcutWithDefaultsKey: @"SwitchProxyMode" + toAction:^{ + [[NSNotificationCenter defaultCenter] postNotificationName: @"NOTIFY_SWITCH_PROXY_MODE_SHORTCUT" object: nil]; + }]; +} + +@end diff --git a/V2RayX/ToastWindowController.h b/V2RayX/ToastWindowController.h new file mode 100644 index 0000000..945d754 --- /dev/null +++ b/V2RayX/ToastWindowController.h @@ -0,0 +1,16 @@ +// +// ToastWindowController.h +// V2RayX +// +// Created by Jarvis on 2018/8/28. +// Copyright © 2018年 Project V2Ray. All rights reserved. +// + +#import + +@interface ToastWindowController : NSWindowController + +@property (strong) NSString *message; + +- (void)fadeInHud; +@end diff --git a/V2RayX/ToastWindowController.m b/V2RayX/ToastWindowController.m new file mode 100644 index 0000000..8d955e7 --- /dev/null +++ b/V2RayX/ToastWindowController.m @@ -0,0 +1,112 @@ +// +// ToastWindowController.m +// V2RayX +// +// Created by Jarvis on 2018/8/28. +// Copyright © 2018年 Project V2Ray. All rights reserved. +// + +#import "ToastWindowController.h" +#import + +@interface ToastWindowController () +@property (weak) IBOutlet NSView *panelView; +@property (weak) IBOutlet NSTextField *titleTextField; +@property (strong) NSTimer *timerToFadeOut; +@property (assign) BOOL fadingOut; +@end + +@implementation ToastWindowController + +- (void)windowDidLoad { + [super windowDidLoad]; + + self.shouldCascadeWindows = NO; + + if (self.window) { + NSWindow *win = self.window; + [win setOpaque:NO]; + [win setBackgroundColor:[NSColor clearColor]]; + [win setStyleMask:NSWindowStyleMaskBorderless]; + [win setHidesOnDeactivate:NO]; + [win setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; + [win setLevel:NSFloatingWindowLevel]; + [win orderFrontRegardless]; + } + CALayer *viewLayer = [[CALayer alloc] init]; + [viewLayer setBackgroundColor: CGColorCreateGenericRGB(0.05, 0.05, 0.05, 0.75)]; + [viewLayer setCornerRadius:18.0]; + self.panelView.wantsLayer = YES; + self.panelView.layer = viewLayer; + self.panelView.layer.opaque = 0.0; + self.titleTextField.stringValue = self.message; + + [self setupHud]; +} + +- (void)setupHud { + [self.titleTextField sizeToFit]; + CGFloat kHudHorizontalMargin = 30; + CGFloat kHudHeight = 90.0; + + CGRect labelFrame = self.titleTextField.frame; + CGRect hubWindowFrame = self.window.frame; + hubWindowFrame.size.width = labelFrame.size.width + kHudHorizontalMargin * 2; + hubWindowFrame.size.height = kHudHeight; + + NSRect screenRect = NSScreen.screens[0].visibleFrame; + hubWindowFrame.origin.x = (screenRect.size.width - hubWindowFrame.size.width) * 0.5; + hubWindowFrame.origin.y = (screenRect.size.height - hubWindowFrame.size.height) * 0.5; + [self.window setFrame:hubWindowFrame display:YES]; + + NSRect viewFrame = hubWindowFrame; + viewFrame.origin.x = 0; + viewFrame.origin.y = 0; + self.panelView.frame = viewFrame; + + labelFrame.origin.x = kHudHorizontalMargin; + labelFrame.origin.y = (hubWindowFrame.size.height - labelFrame.size.height) * 0.5; + self.titleTextField.frame = labelFrame; +} + +- (void)fadeInHud { + if (_timerToFadeOut) { + [_timerToFadeOut invalidate]; + _timerToFadeOut = nil; + } + + _fadingOut = NO; + + [CATransaction begin]; + [CATransaction setAnimationDuration:0.35]; + [CATransaction setCompletionBlock:^{ + [self didFadeIn]; + }]; + self.panelView.layer.opacity = 1.0; + [CATransaction commit]; +} + +- (void)didFadeIn { + _timerToFadeOut = [NSTimer scheduledTimerWithTimeInterval:0.35 target:self selector:@selector(fadeOutHud) userInfo:nil repeats:NO]; +} + +- (void)fadeOutHud { + _fadingOut = YES; + + [CATransaction begin]; + [CATransaction setAnimationDuration:0.35]; + [CATransaction setCompletionBlock:^{ + [self didFadeOut]; + }]; + self.panelView.layer.opacity = 0.0; + [CATransaction commit]; +} + +- (void)didFadeOut { + if (_fadingOut) { + [self.window orderOut:self]; + } + _fadingOut = NO; +} + +@end diff --git a/V2RayX/ToastWindowController.xib b/V2RayX/ToastWindowController.xib new file mode 100644 index 0000000..02a2032 --- /dev/null +++ b/V2RayX/ToastWindowController.xib @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +