├── .gitignore ├── README.md ├── bundles ├── AfloatX_1.3.6.zip ├── Alcatraz_1.2.1.zip ├── BatteryExtra_1.2.zip ├── BatteryExtra_1.3.1.zip ├── BetterDictionary_0.992.zip ├── ChromeDimBackground_0.1.1.zip ├── CustomNC_1.5.zip ├── DarkDock_1.0.zip ├── FScriptLoader_1.1.zip ├── GlobalNoFullscreenButton_1.0.zip ├── GlobalNoWindowIcon_1.0.zip ├── GlobalNoWindowTitle_1.0.zip ├── GreaseKit_1.7.zip ├── Jello_0.0.2.zip ├── LiftOff_1.1.6.zip ├── MenuBarHider_1.0.zip ├── MouseTerm_plus-1.0a10.zip ├── PDFReaderPlugin_1.2.zip ├── PreviewNoSidebar_1.0.zip ├── RadonChrome_1.0.zip ├── SIMBL-FScript_1.0.zip ├── SafariStand_9.0.217Yosemite.zip ├── ScrollbarsOnTheLeft_1.0.zip ├── Spaytify_1.0.1.zip ├── TerminalCopyOnSelect_0.1.2.zip ├── Termite_1.0.42.zip ├── TypeStatus_1.0.zip ├── WriteReceipt_1.1.zip ├── cosyTabs_1.4.2.zip ├── lightWin_0.1.14.zip ├── message-indicator_1.1.0.zip ├── noTitleBar-Terminal_0.2.zip ├── spaces-renamer_1.4.1.zip ├── spaces-renamer_1.7.0.zip └── spaces-renamer_1.7.1.zip ├── icon.png ├── images ├── com.alexbeals.SpacesRenamer │ ├── 01.png │ ├── 02.png │ ├── 03.png │ └── icon.png ├── com.decode.JelloInject │ ├── 01.png │ └── icon.png ├── com.github.jslegendre.AfloatX │ ├── 01.png │ └── 02.png ├── com.github.jslegendre.LiftOff │ ├── 01.png │ ├── 02.png │ ├── 03.png │ ├── 04.png │ ├── 05.png │ ├── 06.png │ ├── banner.png │ └── icon.png └── com.github.jslegendre.Termite │ └── 01.png ├── packages_v2.plist ├── repoUpdate ├── resource.plist └── templates ├── Example Plugin ├── template.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── template │ ├── Info.plist │ ├── README.md │ ├── ZKSwizzle.h │ ├── ZKSwizzle.m │ └── bundle.m └── Xcode Template └── MacForge Plugin.xctemplate ├── Info.plist ├── PrefixHeader.pch ├── TemplateIcon.icns ├── TemplateInfo.plist ├── ZKSwizzle ├── ZKSwizzle.h └── ZKSwizzle.m ├── ___PACKAGENAME___.h └── ___PACKAGENAME___.m /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | ## Build generated 3 | build/ 4 | DerivedData/ 5 | 6 | ## Various settings 7 | *.pbxuser 8 | !default.pbxuser 9 | *.mode1v3 10 | !default.mode1v3 11 | *.mode2v3 12 | !default.mode2v3 13 | *.perspectivev3 14 | !default.perspectivev3 15 | xcuserdata/ 16 | 17 | ## Other 18 | *.moved-aside 19 | *.xccheckout 20 | *.xcscmblueprint 21 | *.DS_Store 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MacForge Plugins 2 | ================= 3 | Package list repository for [MacForge](https://github.com/w0lfschild/MacForge), the MacOS Plugin Manager. 4 | 5 | To contribute your own package: 6 | 7 | - Fork this project 8 | - Add your compiled and zipped plugin to the bundles folder 9 | - Edit [packages_v2.plist](https://github.com/w0lfschild/macplugins/blob/master/packages_v2.plist) to include your submission 10 | - Submit a pull request 11 | 12 | Every package uses this format: 13 | 14 | ``` 15 | Dict: 16 | key: bundleID 17 | Dict: 18 | key: apps 19 | key: author 20 | key: compat 21 | key: contact 22 | key: date 23 | key: description 24 | key: donate 25 | key: filename (required) 26 | key: homepage 27 | key: name (required) 28 | key: package (required) 29 | key: price 30 | key: size 31 | key: target 32 | key-array: targets 33 | Dict: 34 | key: BundleIdentifier 35 | key: version (required) 36 | key: webpage 37 | ``` 38 | 39 | Example: 40 | 41 | 42 | ``` 43 | 44 | 45 | 46 | 47 | org.w0lf.winBuddy 48 | 49 | apps 50 | System 51 | author 52 | Wolfgang Baird 53 | compat 54 | macOS 10.9+ 55 | contact 56 | support@macenhance.com 57 | date 58 | Dec 20, 2016 59 | description 60 | Removes window shadow, black border and more 61 | descriptionShort 62 | 63 | donate 64 | https://www.paypal.me/w0lfspapa 65 | filename 66 | /bundles/winBuddy_0.2.7.zip 67 | homepage 68 | 69 | name 70 | winBuddy 71 | package 72 | org.w0lf.winBuddy 73 | price 74 | Free 75 | size 76 | 23087 77 | target 78 | null 79 | targets 80 | 81 | 82 | BundleIdentifier 83 | * 84 | 85 | 86 | version 87 | 0.2.7 88 | webpage 89 | 90 | 91 | 92 | 93 | ``` 94 | -------------------------------------------------------------------------------- /bundles/AfloatX_1.3.6.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/AfloatX_1.3.6.zip -------------------------------------------------------------------------------- /bundles/Alcatraz_1.2.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/Alcatraz_1.2.1.zip -------------------------------------------------------------------------------- /bundles/BatteryExtra_1.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/BatteryExtra_1.2.zip -------------------------------------------------------------------------------- /bundles/BatteryExtra_1.3.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/BatteryExtra_1.3.1.zip -------------------------------------------------------------------------------- /bundles/BetterDictionary_0.992.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/BetterDictionary_0.992.zip -------------------------------------------------------------------------------- /bundles/ChromeDimBackground_0.1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/ChromeDimBackground_0.1.1.zip -------------------------------------------------------------------------------- /bundles/CustomNC_1.5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/CustomNC_1.5.zip -------------------------------------------------------------------------------- /bundles/DarkDock_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/DarkDock_1.0.zip -------------------------------------------------------------------------------- /bundles/FScriptLoader_1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/FScriptLoader_1.1.zip -------------------------------------------------------------------------------- /bundles/GlobalNoFullscreenButton_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/GlobalNoFullscreenButton_1.0.zip -------------------------------------------------------------------------------- /bundles/GlobalNoWindowIcon_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/GlobalNoWindowIcon_1.0.zip -------------------------------------------------------------------------------- /bundles/GlobalNoWindowTitle_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/GlobalNoWindowTitle_1.0.zip -------------------------------------------------------------------------------- /bundles/GreaseKit_1.7.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/GreaseKit_1.7.zip -------------------------------------------------------------------------------- /bundles/Jello_0.0.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/Jello_0.0.2.zip -------------------------------------------------------------------------------- /bundles/LiftOff_1.1.6.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/LiftOff_1.1.6.zip -------------------------------------------------------------------------------- /bundles/MenuBarHider_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/MenuBarHider_1.0.zip -------------------------------------------------------------------------------- /bundles/MouseTerm_plus-1.0a10.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/MouseTerm_plus-1.0a10.zip -------------------------------------------------------------------------------- /bundles/PDFReaderPlugin_1.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/PDFReaderPlugin_1.2.zip -------------------------------------------------------------------------------- /bundles/PreviewNoSidebar_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/PreviewNoSidebar_1.0.zip -------------------------------------------------------------------------------- /bundles/RadonChrome_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/RadonChrome_1.0.zip -------------------------------------------------------------------------------- /bundles/SIMBL-FScript_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/SIMBL-FScript_1.0.zip -------------------------------------------------------------------------------- /bundles/SafariStand_9.0.217Yosemite.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/SafariStand_9.0.217Yosemite.zip -------------------------------------------------------------------------------- /bundles/ScrollbarsOnTheLeft_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/ScrollbarsOnTheLeft_1.0.zip -------------------------------------------------------------------------------- /bundles/Spaytify_1.0.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/Spaytify_1.0.1.zip -------------------------------------------------------------------------------- /bundles/TerminalCopyOnSelect_0.1.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/TerminalCopyOnSelect_0.1.2.zip -------------------------------------------------------------------------------- /bundles/Termite_1.0.42.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/Termite_1.0.42.zip -------------------------------------------------------------------------------- /bundles/TypeStatus_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/TypeStatus_1.0.zip -------------------------------------------------------------------------------- /bundles/WriteReceipt_1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/WriteReceipt_1.1.zip -------------------------------------------------------------------------------- /bundles/cosyTabs_1.4.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/cosyTabs_1.4.2.zip -------------------------------------------------------------------------------- /bundles/lightWin_0.1.14.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/lightWin_0.1.14.zip -------------------------------------------------------------------------------- /bundles/message-indicator_1.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/message-indicator_1.1.0.zip -------------------------------------------------------------------------------- /bundles/noTitleBar-Terminal_0.2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/noTitleBar-Terminal_0.2.zip -------------------------------------------------------------------------------- /bundles/spaces-renamer_1.4.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/spaces-renamer_1.4.1.zip -------------------------------------------------------------------------------- /bundles/spaces-renamer_1.7.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/spaces-renamer_1.7.0.zip -------------------------------------------------------------------------------- /bundles/spaces-renamer_1.7.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/bundles/spaces-renamer_1.7.1.zip -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/icon.png -------------------------------------------------------------------------------- /images/com.alexbeals.SpacesRenamer/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.alexbeals.SpacesRenamer/01.png -------------------------------------------------------------------------------- /images/com.alexbeals.SpacesRenamer/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.alexbeals.SpacesRenamer/02.png -------------------------------------------------------------------------------- /images/com.alexbeals.SpacesRenamer/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.alexbeals.SpacesRenamer/03.png -------------------------------------------------------------------------------- /images/com.alexbeals.SpacesRenamer/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.alexbeals.SpacesRenamer/icon.png -------------------------------------------------------------------------------- /images/com.decode.JelloInject/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.decode.JelloInject/01.png -------------------------------------------------------------------------------- /images/com.decode.JelloInject/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.decode.JelloInject/icon.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.AfloatX/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.AfloatX/01.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.AfloatX/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.AfloatX/02.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.LiftOff/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.LiftOff/01.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.LiftOff/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.LiftOff/02.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.LiftOff/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.LiftOff/03.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.LiftOff/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.LiftOff/04.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.LiftOff/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.LiftOff/05.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.LiftOff/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.LiftOff/06.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.LiftOff/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.LiftOff/banner.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.LiftOff/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.LiftOff/icon.png -------------------------------------------------------------------------------- /images/com.github.jslegendre.Termite/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/images/com.github.jslegendre.Termite/01.png -------------------------------------------------------------------------------- /packages_v2.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ca.adambell.DarkDock 6 | 7 | apps 8 | Dock 9 | author 10 | Adam Bell 11 | compat 12 | macOS 10.9+ 13 | contact 14 | adam@adambell.ca 15 | date 16 | Dec 21, 2016 17 | description 18 | Force the Dock to display in Dark Mode 19 | descriptionShort 20 | Force the Dock to display in Dark Mode 21 | donate 22 | 23 | filename 24 | /bundles/DarkDock_1.0.zip 25 | homepage 26 | https://github.com/b3ll/DarkDock/ 27 | name 28 | DarkDock 29 | package 30 | ca.adambell.DarkDock 31 | price 32 | Free 33 | size 34 | 19941 35 | targets 36 | 37 | 38 | BundleIdentifier 39 | com.apple.dock.extra 40 | 41 | 42 | BundleIdentifier 43 | com.apple.dock 44 | 45 | 46 | version 47 | 1.0 48 | webpage 49 | 50 | 51 | com.BenTrask.ScrollbarsOnTheLeft 52 | 53 | apps 54 | System 55 | author 56 | Ben Trask 57 | compat 58 | macOS 10.9+ 59 | contact 60 | bentrask@comcast.net 61 | date 62 | Dec 21, 2016 63 | description 64 | Change scrollbar placement to the left side 65 | descriptionShort 66 | Change scrollbar placement to the left side 67 | donate 68 | 69 | filename 70 | /bundles/ScrollbarsOnTheLeft_1.0.zip 71 | homepage 72 | https://github.com/btrask/ScrollbarsOnTheLeft 73 | name 74 | ScrollbarsOnTheLeft 75 | package 76 | com.BenTrask.ScrollbarsOnTheLeft 77 | price 78 | Free 79 | size 80 | 9786 81 | targets 82 | 83 | 84 | BundleIdentifier 85 | * 86 | 87 | 88 | version 89 | 1.0 90 | webpage 91 | 92 | 93 | com.alexbeals.SpacesRenamer 94 | 95 | apps 96 | Dock 97 | author 98 | Alex Beals 99 | compat 100 | macOS 10.10+ 101 | contact 102 | 103 | customIcon 104 | 105 | date 106 | Aug 05, 2019 107 | description 108 | Simple menubar tool that lets you customize the names of your spaces to anything you want. 109 | descriptionShort 110 | Rename spaces on macOS 111 | donate 112 | 113 | filename 114 | /bundles/spaces-renamer_1.7.1.zip 115 | hasPreview 116 | 117 | homepage 118 | https://alexbeals.com/ 119 | icon 120 | /images/com.alexbeals.SpacesRenamer/icon.png 121 | name 122 | spaces-renamer 123 | package 124 | com.alexbeals.SpacesRenamer 125 | payed 126 | 127 | price 128 | $0.00 129 | size 130 | 7991083 131 | targets 132 | 133 | 134 | BundleIdentifier 135 | com.apple.dock 136 | 137 | 138 | type 139 | app 140 | version 141 | 1.7.1 142 | webpage 143 | https://alexbeals.com/ 144 | 145 | com.decode.JelloInject 146 | 147 | apps 148 | System 149 | author 150 | iamDecode 151 | compat 152 | macOS 10.9+ 153 | contact 154 | iamdecode@me.com 155 | customIcon 156 | 157 | date 158 | Mar 17, 2020 159 | description 160 | A wobbly windows implementation for MacOS inspired by Compiz for Linux. 161 | descriptionShort 162 | A wobbly windows implementation for MacOS inspired by Compiz for Linux. 163 | donate 164 | https://www.paypal.me/iamdecode 165 | filename 166 | /bundles/Jello_0.0.2.zip 167 | hasPreview 168 | 169 | homepage 170 | https://github.com/iamDecode/Jello 171 | icon 172 | /images/com.decode.JelloInject/icon.png 173 | name 174 | Jello 175 | package 176 | com.decode.JelloInject 177 | price 178 | Free 179 | size 180 | 3293476 181 | targets 182 | 183 | 184 | BundleIdentifier 185 | * 186 | 187 | 188 | version 189 | 0.0.2 190 | webpage 191 | 192 | 193 | com.elanini.PreviewNoSidebar 194 | 195 | apps 196 | Preview 197 | author 198 | Elanini 199 | compat 200 | macOS 10.9+ 201 | contact 202 | 203 | date 204 | Dec 21, 2016 205 | description 206 | No sidebar in preview 207 | descriptionShort 208 | No sidebar in preview 209 | donate 210 | 211 | filename 212 | /bundles/PreviewNoSidebar_1.0.zip 213 | homepage 214 | https://github.com/elanini/PreviewNoSidebar 215 | name 216 | PreviewNoSidebar 217 | package 218 | com.elanini.PreviewNoSidebar 219 | price 220 | Free 221 | size 222 | 11061 223 | targets 224 | 225 | 226 | BundleIdentifier 227 | com.apple.Preview 228 | 229 | 230 | version 231 | 1.0 232 | webpage 233 | 234 | 235 | com.github.jslegendre.AfloatX 236 | 237 | apps 238 | System 239 | author 240 | Jeremy Legendre 241 | compat 242 | macOS 10.14+ 243 | contact 244 | jslegendre@gmail.com 245 | date 246 | May 22, 2020 247 | description 248 | Although AfloatX has some of the same features as Afloat, it is not meant to be a clone. AfloatX is a simple and unobtrusive plugin made to give you some additional window management features. 249 | Current features are: 250 | Keep window on top (floating window) 251 | Keep window on behind all other windows 252 | Transient mode: Always come to focus in current space. Won't force you back to that windows last active space 253 | Sticky mode: Window stays visible on all spaces 254 | Invert window color 255 | Click-Through window: Window is invisible to clicks (best paired with a floating window) 256 | Outline Window: Outline window with 1 of 8 colors 257 | Window transparency 258 | descriptionShort 259 | A powerful yet discreet plugin to add extra features to your windows and window management 260 | donate 261 | https://paypal.me/jslegendre 262 | filename 263 | /bundles/AfloatX_1.3.6.zip 264 | hasPreview 265 | 266 | homepage 267 | https://github.com/jslegendre/AfloatX 268 | name 269 | AfloatX 270 | package 271 | com.github.jslegendre.AfloatX 272 | price 273 | $0.00 274 | size 275 | 347367 276 | targets 277 | 278 | 279 | BundleIdentifier 280 | * 281 | 282 | 283 | version 284 | 1.3.6 285 | webpage 286 | https://github.com/jslegendre/AfloatX 287 | 288 | com.github.jslegendre.LiftOff 289 | 290 | apps 291 | Dock 292 | author 293 | Jeremy Legendre 294 | compat 295 | macOS 10.13+ 296 | contact 297 | jslegendre@gmail.com 298 | customIcon 299 | 300 | date 301 | Mar 30, 2020 302 | description 303 | An awesome plugin that displays the launchpad on top of the Desktop at all times making it easier than ever to access your apps! 304 | descriptionShort 305 | Overlay Launchpad on the Desktop 306 | donate 307 | 308 | filename 309 | /bundles/LiftOff_1.1.6.zip 310 | hasPreview 311 | 312 | homepage 313 | https://jslegendre.github.com/ 314 | icon 315 | /images/com.github.jslegendre.LiftOff/icon.png 316 | name 317 | LiftOff 318 | package 319 | com.github.jslegendre.LiftOff 320 | paddle 321 | 322 | apikey 323 | 508205c7de527e9cc702cd1b1e5e2733 324 | productid 325 | 570933 326 | vendorid 327 | 102003 328 | 329 | payed 330 | 331 | price 332 | $2.99 333 | productID 334 | 570933 335 | size 336 | 2498937 337 | targets 338 | 339 | 340 | BundleIdentifier 341 | com.apple.dock 342 | 343 | 344 | type 345 | Bundle 346 | version 347 | 1.1.6 348 | 349 | com.github.jslegendre.Termite 350 | 351 | apps 352 | Bartender 3 353 | author 354 | Jeremy Legendre 355 | compat 356 | macOS 10.13+ 357 | contact 358 | jslegendre@gmail.com 359 | date 360 | Oct 26, 2019 361 | description 362 | Expand Bartender 3 on mouse over. Now you won't have to endure the long and arduous task of clicking on the little Bartender button to toggle your other status bar items. 363 | descriptionShort 364 | Expand Bartender 3 on mouse over 365 | filename 366 | /bundles/Termite_1.0.42.zip 367 | hasPreview 368 | 369 | homepage 370 | https://github.com/jslegendre/Termite 371 | name 372 | Termite 373 | package 374 | com.github.jslegendre.Termite 375 | price 376 | $0.00 377 | size 378 | 5852 379 | targets 380 | 381 | 382 | BundleIdentifier 383 | com.surteesstudios.Bartender 384 | 385 | 386 | version 387 | 1.0.42 388 | webpage 389 | https://github.com/jslegendre/Termite 390 | 391 | com.hackingdartmouth.message-indicator 392 | 393 | apps 394 | Messages 395 | author 396 | Alex Beals 397 | compat 398 | macOS 10.9+ 399 | contact 400 | alexcbeals+simbl@gmail.com 401 | date 402 | Apr 14, 2018 403 | description 404 | This plugin adds a small gray indicator under the blue unread one to Messages if you weren't the last person to respond, and it's not a group chat. 405 | descriptionShort 406 | A Messages indicator for when you haven't responded 407 | donate 408 | https://www.paypal.me/w0lfspapa 409 | filename 410 | /bundles/message-indicator_1.1.0.zip 411 | homepage 412 | https://github.com/dado3212/message-indicator 413 | name 414 | message-indicator 415 | package 416 | com.hackingdartmouth.message-indicator 417 | price 418 | Free 419 | size 420 | 20002 421 | targets 422 | 423 | 424 | BundleIdentifier 425 | com.apple.iChat 426 | 427 | 428 | version 429 | 1.1.0 430 | webpage 431 | 432 | 433 | com.hetima.SafariStand 434 | 435 | apps 436 | Safari 437 | author 438 | Hetima 439 | compat 440 | Safari 9 441 | contact 442 | hetima@hetima.com 443 | date 444 | Dec 21, 2016 445 | description 446 | Improvements to Safari 447 | descriptionShort 448 | Improvements to Safari 449 | donate 450 | 451 | filename 452 | /bundles/SafariStand_9.0.217Yosemite.zip 453 | homepage 454 | https://github.com/hetima/SafariStand/ 455 | name 456 | SafariStand 457 | package 458 | com.hetima.SafariStand 459 | price 460 | Free 461 | size 462 | 346315 463 | targets 464 | 465 | 466 | BundleIdentifier 467 | com.apple.Safari 468 | 469 | 470 | version 471 | 9.0.217Yosemite 472 | webpage 473 | 474 | 475 | com.kuglee.batteryextra 476 | 477 | apps 478 | Battery Statusbar Item 479 | author 480 | Gábor Librecz 481 | compat 482 | macOS 10.12+ 483 | contact 484 | kuglee@gmail.com 485 | date 486 | May 05, 2018 487 | description 488 | Makes the Battery status indicator work just like how it did back in Mac OS X Lion (10.7). 489 | descriptionShort 490 | Plugin for the Battery status indicator 491 | donate 492 | https://www.paypal.me/w0lfspapa 493 | filename 494 | /bundles/BatteryExtra_1.3.1.zip 495 | homepage 496 | https://github.com/kuglee/BatteryExtra 497 | name 498 | BatteryExtra 499 | package 500 | com.kuglee.batteryextra 501 | price 502 | $0.00 503 | size 504 | 6476161 505 | targets 506 | 507 | 508 | BundleIdentifier 509 | com.apple.systemuiserver 510 | 511 | 512 | version 513 | 1.3.1 514 | webpage 515 | https://github.com/kuglee/BatteryExtra 516 | 517 | com.mneorr.Alcatraz 518 | 519 | apps 520 | Xcode 521 | author 522 | macEnhance 523 | compat 524 | Xcode 7+ 525 | contact 526 | aguywithlonghair@gmail.com 527 | date 528 | Apr 14, 2018 529 | description 530 | Plugin manager for Xcode 531 | descriptionShort 532 | Plugin manager for Xcode 533 | donate 534 | https://www.paypal.me/w0lfspapa 535 | filename 536 | /bundles/Alcatraz_1.2.1.zip 537 | homepage 538 | http://alcatraz.io/ 539 | name 540 | Alcatraz 541 | package 542 | com.mneorr.Alcatraz 543 | price 544 | Free 545 | size 546 | 138158 547 | targets 548 | 549 | 550 | BundleIdentifier 551 | com.apple.dt.Xcode 552 | 553 | 554 | version 555 | 1.2.1 556 | webpage 557 | http://alcatraz.io/ 558 | 559 | com.pooriaazimi.betterdictionary 560 | 561 | apps 562 | Dictionary 563 | author 564 | Pooria Azimi 565 | compat 566 | macOS 10.9+ 567 | contact 568 | pooriaazimi@gmail.com 569 | date 570 | Dec 21, 2016 571 | description 572 | Improve the dictionary app 573 | descriptionShort 574 | Improve the dictionary app 575 | donate 576 | 577 | filename 578 | /bundles/BetterDictionary_0.992.zip 579 | homepage 580 | https://github.com/pooriaazimi/BetterDictionary/ 581 | name 582 | BetterDictionary 583 | package 584 | com.pooriaazimi.betterdictionary 585 | price 586 | Free 587 | size 588 | 326967 589 | targets 590 | 591 | 592 | BundleIdentifier 593 | com.apple.Dictionary 594 | 595 | 596 | version 597 | 0.992 598 | webpage 599 | 600 | 601 | com.prestonmueller.RadonChrome 602 | 603 | apps 604 | Google Chrome 605 | author 606 | macEnhance 607 | compat 608 | Chrome 50+ 609 | contact 610 | aguywithlonghair@gmail.com 611 | date 612 | Dec 21, 2016 613 | description 614 | Send Chrome notification to the notification center 615 | descriptionShort 616 | Send Chrome notification to the notification center 617 | donate 618 | https://www.paypal.me/w0lfspapa 619 | filename 620 | /bundles/RadonChrome_1.0.zip 621 | homepage 622 | https://github.com/w0lfschild/RadonChrome/ 623 | name 624 | RadonChrome 625 | package 626 | com.prestonmueller.RadonChrome 627 | price 628 | Free 629 | size 630 | 18454 631 | targets 632 | 633 | 634 | BundleIdentifier 635 | com.google.Chrome 636 | 637 | 638 | BundleIdentifier 639 | com.google.Chrome.canary 640 | 641 | 642 | version 643 | 1.0 644 | webpage 645 | 646 | 647 | com.s21g.TerminalCopyOnSelect 648 | 649 | apps 650 | Terminal 651 | author 652 | Minoru Nakata 653 | compat 654 | macOS 10.9+ 655 | contact 656 | 657 | date 658 | Jan 19, 2017 659 | description 660 | Copy text on selection in Terminal 661 | descriptionShort 662 | Copy text on selection in Terminal 663 | donate 664 | https://www.paypal.me/w0lfspapa 665 | filename 666 | /bundles/TerminalCopyOnSelect_0.1.2.zip 667 | homepage 668 | https://github.com/u-minor/terminalcopyonselect 669 | name 670 | TerminalCopyOnSelect 671 | package 672 | com.s21g.TerminalCopyOnSelect 673 | price 674 | Free 675 | size 676 | 5153 677 | targets 678 | 679 | 680 | BundleIdentifier 681 | com.apple.Terminal 682 | 683 | 684 | version 685 | 0.1.2 686 | webpage 687 | 688 | 689 | com.shishkabibal.WriteReceipt 690 | 691 | apps 692 | Messages 693 | author 694 | Brian 695 | compat 696 | macOS 10.13+ 697 | contact 698 | 699 | date 700 | May 05, 2018 701 | description 702 | plugin for Messages that leaves chats unread (and read receipts unsent) until you begin typing a reply (or press enter) 703 | descriptionShort 704 | Leaves chats unread until you type 705 | donate 706 | 707 | filename 708 | /bundles/WriteReceipt_1.1.zip 709 | homepage 710 | 711 | name 712 | WriteReceipt 713 | package 714 | com.shishkabibal.WriteReceipt 715 | price 716 | $0.00 717 | size 718 | 76074 719 | targets 720 | 721 | 722 | BundleIdentifier 723 | com.apple.iChat 724 | 725 | 726 | version 727 | 1.1 728 | webpage 729 | 730 | 731 | com.yourcompany.MenuBarHider 732 | 733 | apps 734 | System 735 | author 736 | Crazor 737 | compat 738 | macOS 10.9+ 739 | contact 740 | crazor@gmail.com 741 | date 742 | Dec 21, 2016 743 | description 744 | Hide the menubar on OSX 10.10 and below 745 | descriptionShort 746 | Hide the menubar on OSX 10.10 and below 747 | donate 748 | 749 | filename 750 | /bundles/MenuBarHider_1.0.zip 751 | homepage 752 | https://github.com/Crazor/MenuBarHider/ 753 | name 754 | MenuBarHider 755 | package 756 | com.yourcompany.MenuBarHider 757 | price 758 | Free 759 | size 760 | 10978 761 | targets 762 | 763 | 764 | BundleIdentifier 765 | * 766 | 767 | 768 | version 769 | 1.0 770 | webpage 771 | 772 | 773 | info.8-p.GreaseKit 774 | 775 | apps 776 | Safari 777 | author 778 | Kato Kazuyoshi 779 | compat 780 | macOS 10.9+ 781 | contact 782 | aguywithlonghair@gmail.com 783 | date 784 | Apr 14, 2018 785 | description 786 | GreaseKit is a MacForge plugin, that adds user scripting to Safari, Mailplane, Diet Pibb.app and all WebKit applications. 787 | descriptionShort 788 | Adds user scripting to Safari 789 | donate 790 | 791 | filename 792 | /bundles/GreaseKit_1.7.zip 793 | homepage 794 | https://8-p.info/greasekit/ 795 | name 796 | GreaseKit 797 | package 798 | info.8-p.GreaseKit 799 | price 800 | $0.00 801 | size 802 | 75609 803 | targets 804 | 805 | 806 | BundleIdentifier 807 | * 808 | 809 | 810 | version 811 | 1.7 812 | webpage 813 | https://8-p.info/greasekit/ 814 | 815 | io.callcc.Spaytify 816 | 817 | apps 818 | Spotify 819 | author 820 | Matt Green 821 | compat 822 | macOS 10.9+ 823 | contact 824 | MattGreenrocks@gmail.com 825 | date 826 | Dec 21, 2016 827 | description 828 | Disable Spotify's badging/bouncing of the dock icon 829 | descriptionShort 830 | Disable Spotify's badging/bouncing of the dock icon 831 | donate 832 | 833 | filename 834 | /bundles/Spaytify_1.0.1.zip 835 | homepage 836 | https://github.com/mattgreen/spaytify 837 | name 838 | Spaytify 839 | package 840 | io.callcc.Spaytify 841 | price 842 | Free 843 | size 844 | 4799 845 | targets 846 | 847 | 848 | BundleIdentifier 849 | com.spotify.client 850 | 851 | 852 | version 853 | 1.0.1 854 | webpage 855 | 856 | 857 | me.choco.noTitleBarTerminal 858 | 859 | apps 860 | 861 | author 862 | macEnhance 863 | compat 864 | macOS 10.9+ 865 | contact 866 | aguywithlonghair@gmail.com 867 | date 868 | Apr 14, 2018 869 | description 870 | Removes the titlebar from the Terminal for a clean look while coding. 871 | descriptionShort 872 | No tiltle bar in the Terminal app 873 | donate 874 | https://www.paypal.me/w0lfspapa 875 | filename 876 | /bundles/noTitleBar-Terminal_0.2.zip 877 | homepage 878 | 879 | name 880 | noTitleBar-Terminal 881 | package 882 | me.choco.noTitleBarTerminal 883 | price 884 | $0.00 885 | size 886 | 10755 887 | targets 888 | 889 | 890 | BundleIdentifier 891 | com.apple.Terminal 892 | 893 | 894 | version 895 | 0.2 896 | webpage 897 | 898 | 899 | me.inket.CustomNC 900 | 901 | apps 902 | Notification Center 903 | author 904 | Mahdi Bchetnia 905 | compat 906 | macOS 10.9+ 907 | contact 908 | mahdi@outlook.com 909 | date 910 | Dec 21, 2016 911 | description 912 | Personalise your Notification Center banners and alerts 913 | descriptionShort 914 | Personalise your Notification Center banners and alerts 915 | donate 916 | 917 | filename 918 | /bundles/CustomNC_1.5.zip 919 | homepage 920 | https://github.com/inket/CustomNC 921 | name 922 | CustomNC 923 | package 924 | me.inket.CustomNC 925 | price 926 | Free 927 | size 928 | 21336 929 | targets 930 | 931 | 932 | BundleIdentifier 933 | com.apple.notificationcenterui 934 | 935 | 936 | version 937 | 1.5 938 | webpage 939 | 940 | 941 | me.inket.GlobalNoFullscreenButton 942 | 943 | apps 944 | System 945 | author 946 | macEnhance 947 | compat 948 | macOS 10.9+ 949 | contact 950 | mahdi@outlook.com 951 | date 952 | Apr 14, 2018 953 | description 954 | Hides fullscreen button from windows. 955 | descriptionShort 956 | Hides fullscreen button from windows. 957 | donate 958 | 959 | filename 960 | /bundles/GlobalNoFullscreenButton_1.0.zip 961 | homepage 962 | https://github.com/inket 963 | name 964 | GlobalNoFullscreenButton 965 | package 966 | me.inket.GlobalNoFullscreenButton 967 | price 968 | $0.00 969 | size 970 | 5252 971 | targets 972 | 973 | 974 | BundleIdentifier 975 | * 976 | 977 | 978 | version 979 | 1.0 980 | webpage 981 | 982 | 983 | me.inket.GlobalNoWindowIcon 984 | 985 | apps 986 | System 987 | author 988 | macEnhance 989 | compat 990 | macOS 10.9+ 991 | contact 992 | mahdi@outlook.com 993 | date 994 | Apr 14, 2018 995 | description 996 | Hides window icons on (almost) all apps. 997 | descriptionShort 998 | Hides window icons on (almost) all apps. 999 | donate 1000 | 1001 | filename 1002 | /bundles/GlobalNoWindowIcon_1.0.zip 1003 | homepage 1004 | https://github.com/inket 1005 | name 1006 | GlobalNoWindowIcon 1007 | package 1008 | me.inket.GlobalNoWindowIcon 1009 | price 1010 | $0.00 1011 | size 1012 | 16052 1013 | targets 1014 | 1015 | 1016 | BundleIdentifier 1017 | * 1018 | 1019 | 1020 | version 1021 | 1.0 1022 | webpage 1023 | 1024 | 1025 | me.inket.GlobalNoWindowTitle 1026 | 1027 | apps 1028 | System 1029 | author 1030 | macEnhance 1031 | compat 1032 | macOS 10.9+ 1033 | contact 1034 | mahdi@outlook.com 1035 | date 1036 | Apr 14, 2018 1037 | description 1038 | Hides window titles+icons. 1039 | descriptionShort 1040 | Hides window titles+icons. 1041 | donate 1042 | 1043 | filename 1044 | /bundles/GlobalNoWindowTitle_1.0.zip 1045 | homepage 1046 | https://github.com/inket 1047 | name 1048 | GlobalNoWindowTitle 1049 | package 1050 | me.inket.GlobalNoWindowTitle 1051 | price 1052 | $0.00 1053 | size 1054 | 8567 1055 | targets 1056 | 1057 | 1058 | BundleIdentifier 1059 | * 1060 | 1061 | 1062 | version 1063 | 1.0 1064 | webpage 1065 | 1066 | 1067 | me.inket.cosyTabs 1068 | 1069 | apps 1070 | Safari 1071 | author 1072 | Mahdi Bchetnia 1073 | compat 1074 | macOS 10.9+ 1075 | contact 1076 | mahdi@outlook.com 1077 | date 1078 | Dec 21, 2016 1079 | description 1080 | Safari 5 tabs on Safari 6+ 1081 | descriptionShort 1082 | Safari 5 tabs on Safari 6+ 1083 | donate 1084 | 1085 | filename 1086 | /bundles/cosyTabs_1.4.2.zip 1087 | homepage 1088 | https://mahdi.jp/apps/cosytabs 1089 | name 1090 | cosyTabs 1091 | package 1092 | me.inket.cosyTabs 1093 | price 1094 | Free 1095 | size 1096 | 16650 1097 | targets 1098 | 1099 | 1100 | BundleIdentifier 1101 | com.apple.Safari 1102 | 1103 | 1104 | version 1105 | 1.4.2 1106 | webpage 1107 | 1108 | 1109 | name.guoc.excerptor.PDFReaderPlugin 1110 | 1111 | apps 1112 | Preview / Skim 1113 | author 1114 | macEnhance 1115 | compat 1116 | macOS 10.10+ 1117 | contact 1118 | guochen42+excerptor@gmail.com 1119 | date 1120 | Apr 14, 2018 1121 | description 1122 | When you read a PDF file, you may want to take some excerpts, like excerpting on physical books (including article name, page number etc.). Via Excerptor, you can take excerpts easily: select text in Preview/Skim and type a shortcut. An excerpt will be stored in pasteboard or a file. The excerpt includes a special link. By clicking the link, Excerptor will open the corresponding file by Preview/Skim, go to the page you want and highlight the excerpt you made, automatically. 1123 | descriptionShort 1124 | Take and locate excerpts in PDF files quickly 1125 | donate 1126 | 1127 | filename 1128 | /bundles/PDFReaderPlugin_1.2.zip 1129 | homepage 1130 | https://github.com/guoc/excerptor 1131 | name 1132 | PDFReaderPlugin 1133 | package 1134 | name.guoc.excerptor.PDFReaderPlugin 1135 | price 1136 | $0.00 1137 | size 1138 | 30097 1139 | targets 1140 | 1141 | 1142 | BundleIdentifier 1143 | com.apple.Preview 1144 | 1145 | 1146 | BundleIdentifier 1147 | net.sourceforge.skim-app.skim 1148 | 1149 | 1150 | version 1151 | 1.2 1152 | webpage 1153 | 1154 | 1155 | org.bitheap.MouseTerm 1156 | 1157 | apps 1158 | Terminal 1159 | author 1160 | Brodie Rao 1161 | compat 1162 | macOS 10.9+ 1163 | contact 1164 | brodie@sf.io 1165 | date 1166 | Dec 21, 2016 1167 | description 1168 | Adds xterm mouse reporting to Terminal 1169 | descriptionShort 1170 | Adds xterm mouse reporting to Terminal 1171 | donate 1172 | 1173 | filename 1174 | /bundles/MouseTerm_plus-1.0a10.zip 1175 | homepage 1176 | https://github.com/brodie/mouseterm 1177 | name 1178 | MouseTerm 1179 | package 1180 | org.bitheap.MouseTerm 1181 | price 1182 | Free 1183 | size 1184 | 76236 1185 | targets 1186 | 1187 | 1188 | BundleIdentifier 1189 | com.apple.Terminal 1190 | 1191 | 1192 | version 1193 | plus-1.0a10 1194 | webpage 1195 | 1196 | 1197 | org.craptech.lightWin 1198 | 1199 | apps 1200 | 1201 | author 1202 | macEnhance 1203 | compat 1204 | macOS 10.9+ 1205 | contact 1206 | aguywithlonghair@gmail.com 1207 | date 1208 | Apr 14, 2018 1209 | description 1210 | Simple bundle to give Terminal a borderless, shadowless look 1211 | descriptionShort 1212 | borderless, shadowless Terminal.app 1213 | donate 1214 | 1215 | filename 1216 | /bundles/lightWin_0.1.14.zip 1217 | homepage 1218 | 1219 | name 1220 | lightWin 1221 | package 1222 | org.craptech.lightWin 1223 | price 1224 | $0.00 1225 | size 1226 | 22098 1227 | targets 1228 | 1229 | 1230 | BundleIdentifier 1231 | com.apple.Terminal 1232 | 1233 | 1234 | version 1235 | 0.1.14 1236 | webpage 1237 | 1238 | 1239 | org.michaelphines.ChromeDimBackground 1240 | 1241 | apps 1242 | Google Chrome 1243 | author 1244 | krackers 1245 | compat 1246 | macOS 10.9+ 1247 | contact 1248 | 1249 | date 1250 | Dec 21, 2016 1251 | description 1252 | Themed tabs change when in the background 1253 | descriptionShort 1254 | Themed tabs change when in the background 1255 | donate 1256 | https://www.paypal.me/w0lfspapa 1257 | filename 1258 | /bundles/ChromeDimBackground_0.1.1.zip 1259 | homepage 1260 | https://github.com/krackers/ChromeDimBackground 1261 | name 1262 | ChromeDimBackground 1263 | package 1264 | org.michaelphines.ChromeDimBackground 1265 | price 1266 | Free 1267 | size 1268 | 17929 1269 | target 1270 | null 1271 | targets 1272 | 1273 | 1274 | BundleIdentifier 1275 | com.google.Chrome 1276 | 1277 | 1278 | BundleIdentifier 1279 | com.google.Chrome.canary 1280 | 1281 | 1282 | version 1283 | 0.1.1 1284 | webpage 1285 | 1286 | 1287 | ws.hbang.typestatus.mac 1288 | 1289 | apps 1290 | Messages 1291 | author 1292 | HASHBANG Productions 1293 | compat 1294 | macOS 10.9+ 1295 | contact 1296 | support@hbang.ws 1297 | date 1298 | Dec 21, 2016 1299 | description 1300 | Disply a notification when others are typing in Messages 1301 | descriptionShort 1302 | Disply a notification when others are typing in Messages 1303 | donate 1304 | https://hbang.ws/donate/ 1305 | filename 1306 | /bundles/TypeStatus_1.0.zip 1307 | homepage 1308 | 1309 | name 1310 | TypeStatus 1311 | package 1312 | ws.hbang.typestatus.mac 1313 | price 1314 | Free 1315 | size 1316 | 16275 1317 | targets 1318 | 1319 | 1320 | BundleIdentifier 1321 | com.apple.iChat 1322 | 1323 | 1324 | version 1325 | 1.0 1326 | webpage 1327 | https://typestatus.com/ 1328 | 1329 | 1330 | 1331 | -------------------------------------------------------------------------------- /repoUpdate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/repoUpdate -------------------------------------------------------------------------------- /resource.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/resource.plist -------------------------------------------------------------------------------- /templates/Example Plugin/template.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FB4907371D62BE6D00FA9D73 /* bundle.m in Sources */ = {isa = PBXBuildFile; fileRef = FB4907361D62BE6D00FA9D73 /* bundle.m */; }; 11 | FB49073F1D62C22D00FA9D73 /* ZKSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = FB49073E1D62C22D00FA9D73 /* ZKSwizzle.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 12 | FB8F32581E09F00D0039C7E0 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = FB8F32571E09F00D0039C7E0 /* README.md */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXFileReference section */ 16 | FB49072D1D62BDF200FA9D73 /* template.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = template.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 17 | FB4907301D62BDF200FA9D73 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 18 | FB4907361D62BE6D00FA9D73 /* bundle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = bundle.m; sourceTree = ""; }; 19 | FB49073D1D62C22D00FA9D73 /* ZKSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZKSwizzle.h; sourceTree = ""; }; 20 | FB49073E1D62C22D00FA9D73 /* ZKSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZKSwizzle.m; sourceTree = ""; }; 21 | FB8F32571E09F00D0039C7E0 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 22 | /* End PBXFileReference section */ 23 | 24 | /* Begin PBXFrameworksBuildPhase section */ 25 | FB49072A1D62BDF200FA9D73 /* Frameworks */ = { 26 | isa = PBXFrameworksBuildPhase; 27 | buildActionMask = 2147483647; 28 | files = ( 29 | ); 30 | runOnlyForDeploymentPostprocessing = 0; 31 | }; 32 | /* End PBXFrameworksBuildPhase section */ 33 | 34 | /* Begin PBXGroup section */ 35 | FB4907241D62BDF200FA9D73 = { 36 | isa = PBXGroup; 37 | children = ( 38 | FB49072F1D62BDF200FA9D73 /* template */, 39 | FB49072E1D62BDF200FA9D73 /* Products */, 40 | ); 41 | sourceTree = ""; 42 | }; 43 | FB49072E1D62BDF200FA9D73 /* Products */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | FB49072D1D62BDF200FA9D73 /* template.bundle */, 47 | ); 48 | name = Products; 49 | sourceTree = ""; 50 | }; 51 | FB49072F1D62BDF200FA9D73 /* template */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | FB4907401D62C23100FA9D73 /* ZKSwizzle */, 55 | FB8F32571E09F00D0039C7E0 /* README.md */, 56 | FB4907301D62BDF200FA9D73 /* Info.plist */, 57 | FB4907361D62BE6D00FA9D73 /* bundle.m */, 58 | ); 59 | path = template; 60 | sourceTree = ""; 61 | }; 62 | FB4907401D62C23100FA9D73 /* ZKSwizzle */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | FB49073D1D62C22D00FA9D73 /* ZKSwizzle.h */, 66 | FB49073E1D62C22D00FA9D73 /* ZKSwizzle.m */, 67 | ); 68 | name = ZKSwizzle; 69 | sourceTree = ""; 70 | }; 71 | /* End PBXGroup section */ 72 | 73 | /* Begin PBXNativeTarget section */ 74 | FB49072C1D62BDF200FA9D73 /* template */ = { 75 | isa = PBXNativeTarget; 76 | buildConfigurationList = FB4907331D62BDF200FA9D73 /* Build configuration list for PBXNativeTarget "template" */; 77 | buildPhases = ( 78 | FB4907291D62BDF200FA9D73 /* Sources */, 79 | FB49072A1D62BDF200FA9D73 /* Frameworks */, 80 | FB49072B1D62BDF200FA9D73 /* Resources */, 81 | FB49073A1D62BF0D00FA9D73 /* 🌀 Increase build number */, 82 | FB4907391D62BECB00FA9D73 /* 🌀 Restart stuff */, 83 | ); 84 | buildRules = ( 85 | ); 86 | dependencies = ( 87 | ); 88 | name = template; 89 | productName = template; 90 | productReference = FB49072D1D62BDF200FA9D73 /* template.bundle */; 91 | productType = "com.apple.product-type.bundle"; 92 | }; 93 | /* End PBXNativeTarget section */ 94 | 95 | /* Begin PBXProject section */ 96 | FB4907251D62BDF200FA9D73 /* Project object */ = { 97 | isa = PBXProject; 98 | attributes = { 99 | LastUpgradeCheck = 0810; 100 | ORGANIZATIONNAME = "Wolfgang Baird"; 101 | TargetAttributes = { 102 | FB49072C1D62BDF200FA9D73 = { 103 | CreatedOnToolsVersion = 8.0; 104 | DevelopmentTeam = EX596BNL45; 105 | ProvisioningStyle = Automatic; 106 | }; 107 | }; 108 | }; 109 | buildConfigurationList = FB4907281D62BDF200FA9D73 /* Build configuration list for PBXProject "template" */; 110 | compatibilityVersion = "Xcode 3.2"; 111 | developmentRegion = English; 112 | hasScannedForEncodings = 0; 113 | knownRegions = ( 114 | English, 115 | en, 116 | ); 117 | mainGroup = FB4907241D62BDF200FA9D73; 118 | productRefGroup = FB49072E1D62BDF200FA9D73 /* Products */; 119 | projectDirPath = ""; 120 | projectRoot = ""; 121 | targets = ( 122 | FB49072C1D62BDF200FA9D73 /* template */, 123 | ); 124 | }; 125 | /* End PBXProject section */ 126 | 127 | /* Begin PBXResourcesBuildPhase section */ 128 | FB49072B1D62BDF200FA9D73 /* Resources */ = { 129 | isa = PBXResourcesBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | ); 133 | runOnlyForDeploymentPostprocessing = 0; 134 | }; 135 | /* End PBXResourcesBuildPhase section */ 136 | 137 | /* Begin PBXShellScriptBuildPhase section */ 138 | FB4907391D62BECB00FA9D73 /* 🌀 Restart stuff */ = { 139 | isa = PBXShellScriptBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | ); 143 | inputPaths = ( 144 | ); 145 | name = "🌀 Restart stuff"; 146 | outputPaths = ( 147 | ); 148 | runOnlyForDeploymentPostprocessing = 0; 149 | shellPath = /bin/sh; 150 | shellScript = "#killall \n"; 151 | }; 152 | FB49073A1D62BF0D00FA9D73 /* 🌀 Increase build number */ = { 153 | isa = PBXShellScriptBuildPhase; 154 | buildActionMask = 2147483647; 155 | files = ( 156 | ); 157 | inputPaths = ( 158 | ); 159 | name = "🌀 Increase build number"; 160 | outputPaths = ( 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | shellPath = /bin/sh; 164 | shellScript = "VERSIONNUM=$(/usr/libexec/PlistBuddy -c \"Print CFBundleShortVersionString\" \"${PROJECT_DIR}/${INFOPLIST_FILE}\")\nNEWSUBVERSION=`echo $VERSIONNUM | awk -F \".\" '{print $3}'`\nNEWSUBVERSION=$(($NEWSUBVERSION + 1))\nNEWVERSIONSTRING=`echo $VERSIONNUM | awk -F \".\" '{print $1 \".\" $2 \".'$NEWSUBVERSION'\" }'`\n/usr/libexec/PlistBuddy -c \"Set :CFBundleShortVersionString $NEWVERSIONSTRING\" \"${PROJECT_DIR}/${INFOPLIST_FILE}\"\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $NEWVERSIONSTRING\" \"${PROJECT_DIR}/${INFOPLIST_FILE}\""; 165 | }; 166 | /* End PBXShellScriptBuildPhase section */ 167 | 168 | /* Begin PBXSourcesBuildPhase section */ 169 | FB4907291D62BDF200FA9D73 /* Sources */ = { 170 | isa = PBXSourcesBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | FB8F32581E09F00D0039C7E0 /* README.md in Sources */, 174 | FB4907371D62BE6D00FA9D73 /* bundle.m in Sources */, 175 | FB49073F1D62C22D00FA9D73 /* ZKSwizzle.m in Sources */, 176 | ); 177 | runOnlyForDeploymentPostprocessing = 0; 178 | }; 179 | /* End PBXSourcesBuildPhase section */ 180 | 181 | /* Begin XCBuildConfiguration section */ 182 | FB4907311D62BDF200FA9D73 /* Debug */ = { 183 | isa = XCBuildConfiguration; 184 | buildSettings = { 185 | ALWAYS_SEARCH_USER_PATHS = NO; 186 | CLANG_ANALYZER_NONNULL = YES; 187 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 188 | CLANG_CXX_LIBRARY = "libc++"; 189 | CLANG_ENABLE_MODULES = YES; 190 | CLANG_ENABLE_OBJC_ARC = YES; 191 | CLANG_WARN_BOOL_CONVERSION = YES; 192 | CLANG_WARN_CONSTANT_CONVERSION = YES; 193 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 194 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 195 | CLANG_WARN_EMPTY_BODY = YES; 196 | CLANG_WARN_ENUM_CONVERSION = YES; 197 | CLANG_WARN_INFINITE_RECURSION = YES; 198 | CLANG_WARN_INT_CONVERSION = YES; 199 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 200 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 201 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 202 | CLANG_WARN_UNREACHABLE_CODE = YES; 203 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 204 | CODE_SIGN_IDENTITY = "-"; 205 | COPY_PHASE_STRIP = NO; 206 | DEBUG_INFORMATION_FORMAT = dwarf; 207 | ENABLE_STRICT_OBJC_MSGSEND = YES; 208 | ENABLE_TESTABILITY = YES; 209 | GCC_C_LANGUAGE_STANDARD = gnu99; 210 | GCC_DYNAMIC_NO_PIC = NO; 211 | GCC_NO_COMMON_BLOCKS = YES; 212 | GCC_OPTIMIZATION_LEVEL = 0; 213 | GCC_PREPROCESSOR_DEFINITIONS = ( 214 | "DEBUG=1", 215 | "$(inherited)", 216 | ); 217 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 218 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 219 | GCC_WARN_UNDECLARED_SELECTOR = YES; 220 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 221 | GCC_WARN_UNUSED_FUNCTION = YES; 222 | GCC_WARN_UNUSED_VARIABLE = YES; 223 | MACOSX_DEPLOYMENT_TARGET = 10.12; 224 | MTL_ENABLE_DEBUG_INFO = YES; 225 | ONLY_ACTIVE_ARCH = YES; 226 | SDKROOT = macosx; 227 | }; 228 | name = Debug; 229 | }; 230 | FB4907321D62BDF200FA9D73 /* Release */ = { 231 | isa = XCBuildConfiguration; 232 | buildSettings = { 233 | ALWAYS_SEARCH_USER_PATHS = NO; 234 | CLANG_ANALYZER_NONNULL = YES; 235 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 236 | CLANG_CXX_LIBRARY = "libc++"; 237 | CLANG_ENABLE_MODULES = YES; 238 | CLANG_ENABLE_OBJC_ARC = YES; 239 | CLANG_WARN_BOOL_CONVERSION = YES; 240 | CLANG_WARN_CONSTANT_CONVERSION = YES; 241 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 242 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 243 | CLANG_WARN_EMPTY_BODY = YES; 244 | CLANG_WARN_ENUM_CONVERSION = YES; 245 | CLANG_WARN_INFINITE_RECURSION = YES; 246 | CLANG_WARN_INT_CONVERSION = YES; 247 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 248 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 249 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 250 | CLANG_WARN_UNREACHABLE_CODE = YES; 251 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 252 | CODE_SIGN_IDENTITY = "-"; 253 | COPY_PHASE_STRIP = NO; 254 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 255 | ENABLE_NS_ASSERTIONS = NO; 256 | ENABLE_STRICT_OBJC_MSGSEND = YES; 257 | GCC_C_LANGUAGE_STANDARD = gnu99; 258 | GCC_NO_COMMON_BLOCKS = YES; 259 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 260 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 261 | GCC_WARN_UNDECLARED_SELECTOR = YES; 262 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 263 | GCC_WARN_UNUSED_FUNCTION = YES; 264 | GCC_WARN_UNUSED_VARIABLE = YES; 265 | MACOSX_DEPLOYMENT_TARGET = 10.12; 266 | MTL_ENABLE_DEBUG_INFO = NO; 267 | SDKROOT = macosx; 268 | }; 269 | name = Release; 270 | }; 271 | FB4907341D62BDF200FA9D73 /* Debug */ = { 272 | isa = XCBuildConfiguration; 273 | buildSettings = { 274 | COMBINE_HIDPI_IMAGES = YES; 275 | DEPLOYMENT_LOCATION = YES; 276 | DEVELOPMENT_TEAM = EX596BNL45; 277 | DSTROOT = /; 278 | INFOPLIST_FILE = template/Info.plist; 279 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Application Support/MacEnhance/Plugins"; 280 | PRODUCT_BUNDLE_IDENTIFIER = com.macenhance.template; 281 | PRODUCT_NAME = "$(TARGET_NAME)"; 282 | WRAPPER_EXTENSION = bundle; 283 | }; 284 | name = Debug; 285 | }; 286 | FB4907351D62BDF200FA9D73 /* Release */ = { 287 | isa = XCBuildConfiguration; 288 | buildSettings = { 289 | COMBINE_HIDPI_IMAGES = YES; 290 | DEPLOYMENT_LOCATION = YES; 291 | DEVELOPMENT_TEAM = EX596BNL45; 292 | DSTROOT = /; 293 | INFOPLIST_FILE = template/Info.plist; 294 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Application Support/MacEnhance/Plugins"; 295 | PRODUCT_BUNDLE_IDENTIFIER = com.macenhance.template; 296 | PRODUCT_NAME = "$(TARGET_NAME)"; 297 | WRAPPER_EXTENSION = bundle; 298 | }; 299 | name = Release; 300 | }; 301 | /* End XCBuildConfiguration section */ 302 | 303 | /* Begin XCConfigurationList section */ 304 | FB4907281D62BDF200FA9D73 /* Build configuration list for PBXProject "template" */ = { 305 | isa = XCConfigurationList; 306 | buildConfigurations = ( 307 | FB4907311D62BDF200FA9D73 /* Debug */, 308 | FB4907321D62BDF200FA9D73 /* Release */, 309 | ); 310 | defaultConfigurationIsVisible = 0; 311 | defaultConfigurationName = Release; 312 | }; 313 | FB4907331D62BDF200FA9D73 /* Build configuration list for PBXNativeTarget "template" */ = { 314 | isa = XCConfigurationList; 315 | buildConfigurations = ( 316 | FB4907341D62BDF200FA9D73 /* Debug */, 317 | FB4907351D62BDF200FA9D73 /* Release */, 318 | ); 319 | defaultConfigurationIsVisible = 0; 320 | defaultConfigurationName = Release; 321 | }; 322 | /* End XCConfigurationList section */ 323 | }; 324 | rootObject = FB4907251D62BDF200FA9D73 /* Project object */; 325 | } 326 | -------------------------------------------------------------------------------- /templates/Example Plugin/template.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /templates/Example Plugin/template.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /templates/Example Plugin/template/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 0.0.1 19 | CFBundleVersion 20 | 0.0.1 21 | NSHumanReadableCopyright 22 | Copyright © 2016 Wolfgang Baird. All rights reserved. 23 | NSPrincipalClass 24 | 25 | SIMBLTargetApplications 26 | 27 | 28 | BundleIdentifier 29 | * 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /templates/Example Plugin/template/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/templates/Example Plugin/template/README.md -------------------------------------------------------------------------------- /templates/Example Plugin/template/ZKSwizzle.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZKSwizzle.h 3 | // ZKSwizzle 4 | // 5 | // Created by Alexander S Zielenski on 7/24/14. 6 | // Copyright (c) 2014 Alexander S Zielenski. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | // This is a class for streamlining swizzling. Simply create a new class of any name you want and 14 | // Example: 15 | /* 16 | @interface ZKHookClass : NSObject 17 | - (NSString *)description; // hooks -description on NSObject 18 | - (void)addedMethod; // all subclasses of NSObject now respond to -addedMethod 19 | @end 20 | 21 | @implementation ZKHookClass 22 | ... 23 | @end 24 | 25 | [ZKSwizzle swizzleClass:ZKClass(ZKHookClass) forClass:ZKClass(destination)]; 26 | */ 27 | 28 | #ifndef ZKSWIZZLE_DEFS 29 | #define ZKSWIZZLE_DEFS 30 | 31 | // CRAZY MACROS FOR DYNAMIC PROTOTYPE CREATION 32 | #define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(0, ## __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5 ,4 ,3 ,2, 1, 0) 33 | #define VA_NUM_ARGS_IMPL(_0, _1,_2,_3,_4,_5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20 ,N,...) N 34 | 35 | #define WRAP0() 36 | #define WRAP1(VARIABLE) , typeof ( VARIABLE ) 37 | #define WRAP2(VARIABLE, ...) WRAP1(VARIABLE) WRAP1(__VA_ARGS__) 38 | #define WRAP3(VARIABLE, ...) WRAP1(VARIABLE) WRAP2(__VA_ARGS__) 39 | #define WRAP4(VARIABLE, ...) WRAP1(VARIABLE) WRAP3(__VA_ARGS__) 40 | #define WRAP5(VARIABLE, ...) WRAP1(VARIABLE) WRAP4(__VA_ARGS__) 41 | #define WRAP6(VARIABLE, ...) WRAP1(VARIABLE) WRAP5(__VA_ARGS__) 42 | #define WRAP7(VARIABLE, ...) WRAP1(VARIABLE) WRAP6(__VA_ARGS__) 43 | #define WRAP8(VARIABLE, ...) WRAP1(VARIABLE) WRAP7(__VA_ARGS__) 44 | #define WRAP9(VARIABLE, ...) WRAP1(VARIABLE) WRAP8(__VA_ARGS__) 45 | #define WRAP10(VARIABLE, ...) WRAP1(VARIABLE) WRAP9(__VA_ARGS__) 46 | #define WRAP11(VARIABLE, ...) WRAP1(VARIABLE) WRAP10(__VA_ARGS__) 47 | #define WRAP12(VARIABLE, ...) WRAP1(VARIABLE) WRAP11(__VA_ARGS__) 48 | #define WRAP13(VARIABLE, ...) WRAP1(VARIABLE) WRAP12(__VA_ARGS__) 49 | #define WRAP14(VARIABLE, ...) WRAP1(VARIABLE) WRAP13(__VA_ARGS__) 50 | #define WRAP15(VARIABLE, ...) WRAP1(VARIABLE) WRAP14(__VA_ARGS__) 51 | #define WRAP16(VARIABLE, ...) WRAP1(VARIABLE) WRAP15(__VA_ARGS__) 52 | #define WRAP17(VARIABLE, ...) WRAP1(VARIABLE) WRAP16(__VA_ARGS__) 53 | #define WRAP18(VARIABLE, ...) WRAP1(VARIABLE) WRAP17(__VA_ARGS__) 54 | #define WRAP19(VARIABLE, ...) WRAP1(VARIABLE) WRAP18(__VA_ARGS__) 55 | #define WRAP20(VARIABLE, ...) WRAP1(VARIABLE) WRAP19(__VA_ARGS__) 56 | 57 | #define CAT(A, B) A ## B 58 | #define INVOKE(MACRO, NUMBER, ...) CAT(MACRO, NUMBER)(__VA_ARGS__) 59 | #define WRAP_LIST(...) INVOKE(WRAP, VA_NUM_ARGS(__VA_ARGS__), __VA_ARGS__) 60 | 61 | // Gets the a class with the name CLASS 62 | #define ZKClass(CLASS) objc_getClass(#CLASS) 63 | 64 | // returns the value of an instance variable. 65 | #if !__has_feature(objc_arc) 66 | #define ZKHookIvar(OBJECT, TYPE, NAME) (*(TYPE *)ZKIvarPointer(OBJECT, NAME)) 67 | #else 68 | #define ZKHookIvar(OBJECT, TYPE, NAME) \ 69 | _Pragma("clang diagnostic push") \ 70 | _Pragma("clang diagnostic ignored \"-Wignored-attributes\"") \ 71 | (*(__unsafe_unretained TYPE *)ZKIvarPointer(OBJECT, NAME)) \ 72 | _Pragma("clang diagnostic pop") 73 | #endif 74 | 75 | //////////////////////////////////////////////////////////////////////////////// 76 | //// Core Macros (For fine-tuned Use) 77 | //////////////////////////////////////////////////////////////////////////////// 78 | // returns the original implementation of the swizzled function or null or not found 79 | #define ZKOrig(TYPE, ...) ((TYPE (*)(id, SEL WRAP_LIST(__VA_ARGS__)))(ZKOriginalImplementation(self, _cmd, __PRETTY_FUNCTION__)))(self, _cmd, ##__VA_ARGS__) 80 | 81 | // returns the original implementation of the superclass of the object swizzled 82 | #define ZKSuper(TYPE, ...) ((TYPE (*)(id, SEL WRAP_LIST(__VA_ARGS__)))(ZKSuperImplementation(self, _cmd, __PRETTY_FUNCTION__)))(self, _cmd, ##__VA_ARGS__) 83 | 84 | #define _ZKSwizzleInterfaceConditionally(CLASS_NAME, TARGET_CLASS, SUPERCLASS, GROUP, IMMEDIATELY) \ 85 | @interface _$ ## CLASS_NAME : SUPERCLASS @end\ 86 | @implementation _$ ## CLASS_NAME\ 87 | + (void)initialize {}\ 88 | @end\ 89 | @interface CLASS_NAME : _$ ## CLASS_NAME @end\ 90 | @implementation CLASS_NAME (ZKSWIZZLE)\ 91 | + (void)load {\ 92 | if (IMMEDIATELY) {\ 93 | [self _ZK_unconditionallySwizzle];\ 94 | } else {\ 95 | _$ZKRegisterInterface(self, #GROUP);\ 96 | }\ 97 | }\ 98 | + (void)_ZK_unconditionallySwizzle {\ 99 | ZKSwizzle(CLASS_NAME, TARGET_CLASS);\ 100 | }\ 101 | @end 102 | 103 | // Bootstraps your swizzling class so that it requires no setup 104 | // outside of this macro call 105 | // If you override +load you must call ZKSwizzle(CLASS_NAME, TARGET_CLASS) 106 | // yourself, otherwise the swizzling would not take place 107 | #define ZKSwizzleInterface(CLASS_NAME, TARGET_CLASS, SUPERCLASS) \ 108 | _ZKSwizzleInterfaceConditionally(CLASS_NAME, TARGET_CLASS, SUPERCLASS, ZK_UNGROUPED, YES) 109 | 110 | // Same as ZKSwizzleInterface, except 111 | #define ZKSwizzleInterfaceGroup(CLASS_NAME, TARGET_CLASS, SUPER_CLASS, GROUP) \ 112 | _ZKSwizzleInterfaceConditionally(CLASS_NAME, TARGET_CLASS, SUPER_CLASS, GROUP, NO) 113 | 114 | //////////////////////////////////////////////////////////////////////////////// 115 | //// Sugar Macros (For general use) 116 | //////////////////////////////////////////////////////////////////////////////// 117 | // Inspired by logos. Credits to @mstg! 118 | 119 | #define __GEN_CLASS(TARGET, LINE) __ZK_## LINE## TARGET 120 | #define _GEN_CLASS(TARGET, LINE) __GEN_CLASS(TARGET, LINE) 121 | #define GEN_CLASS(TARGET) _GEN_CLASS(TARGET, __LINE__) 122 | 123 | #define hook_2(TARGET, GROUP) \ 124 | ZKSwizzleInterfaceGroup(GEN_CLASS(TARGET), TARGET, NSObject, GROUP) @implementation GEN_CLASS(TARGET) 125 | 126 | #define hook_1(TARGET) \ 127 | ZKSwizzleInterface(GEN_CLASS(TARGET), TARGET, NSObject) @implementation GEN_CLASS(TARGET) 128 | 129 | #define endhook @end 130 | 131 | #define _orig(...) ZKOrig(__VA_ARGS__) 132 | #define _super(...) ZKSuper(__VA_ARGS__) 133 | 134 | #define __HOOK(ARGC, ARGS...) hook_ ## ARGC (ARGS) 135 | #define _HOOK(ARGC, ARGS...) __HOOK(ARGC, ARGS) 136 | #define hook(...) _HOOK(VA_NUM_ARGS(__VA_ARGS__), __VA_ARGS__) 137 | #define ctor __attribute__((constructor)) void init() 138 | 139 | #define ZKIgnoreTypes +(BOOL)_ZK_ignoreTypes { return YES; } 140 | 141 | __BEGIN_DECLS 142 | 143 | //////////////////////////////////////////////////////////////////////////////// 144 | //// C Backing (Don't typically call directly) 145 | //////////////////////////////////////////////////////////////////////////////// 146 | 147 | // Make sure to cast this before you use it 148 | typedef id (*ZKIMP)(id, SEL, ...); 149 | 150 | // returns a pointer to the instance variable "name" on the object 151 | void *ZKIvarPointer(id self, const char *name); 152 | // returns the original implementation of a method with selector "sel" of an object hooked by the methods below 153 | ZKIMP ZKOriginalImplementation(id self, SEL sel, const char *info); 154 | // returns the implementation of a method with selector "sel" of the superclass of object 155 | ZKIMP ZKSuperImplementation(id object, SEL sel, const char *info); 156 | 157 | // hooks all the implemented methods of source with destination 158 | // adds any methods that arent implemented on destination to destination that are implemented in source 159 | #define ZKSwizzle(src, dst) _ZKSwizzle(ZKClass(src), ZKClass(dst)) 160 | BOOL _ZKSwizzle(Class src, Class dest); 161 | 162 | #define ZKSwizzleGroup(NAME) _ZKSwizzleGroup(#NAME) 163 | void _$ZKRegisterInterface(Class cls, const char *groupName); 164 | BOOL _ZKSwizzleGroup(const char *groupName); 165 | 166 | // Calls above method with the superclass of source for desination 167 | #define ZKSwizzleClass(src) _ZKSwizzleClass(ZKClass(src)) 168 | BOOL _ZKSwizzleClass(Class cls); 169 | 170 | __END_DECLS 171 | #endif 172 | 173 | -------------------------------------------------------------------------------- /templates/Example Plugin/template/ZKSwizzle.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZKSwizzle.m 3 | // ZKSwizzle 4 | // 5 | // Created by Alexander S Zielenski on 7/24/14. 6 | // Copyright (c) 2014 Alexander S Zielenski. All rights reserved. 7 | // 8 | 9 | #import "ZKSwizzle.h" 10 | static NSMutableDictionary *classTable; 11 | 12 | @interface NSObject (ZKSwizzle) 13 | + (void)_ZK_unconditionallySwizzle; 14 | + (BOOL)_ZK_ignoreTypes; 15 | @end 16 | 17 | void *ZKIvarPointer(id self, const char *name) { 18 | Ivar ivar = class_getInstanceVariable(object_getClass(self), name); 19 | return ivar == NULL ? NULL : (__bridge void *)self + ivar_getOffset(ivar); 20 | } 21 | 22 | static SEL destinationSelectorForSelector(SEL cmd, Class dst) { 23 | return NSSelectorFromString([@"_ZK_old_" stringByAppendingFormat:@"%s_%@", class_getName(dst), NSStringFromSelector(cmd)]); 24 | } 25 | 26 | static Class classFromInfo(const char *info) { 27 | NSUInteger bracket_index = -1; 28 | for (NSUInteger i = 0; i < strlen(info); i++) { 29 | if (info[i] == '[') { 30 | bracket_index = i; 31 | break; 32 | } 33 | } 34 | bracket_index++; 35 | 36 | if (bracket_index == -1) { 37 | [NSException raise:@"Failed to parse info" format:@"Couldn't find swizzle class for info: %s", info]; 38 | return NULL; 39 | } 40 | 41 | char after_bracket[255]; 42 | memcpy(after_bracket, &info[bracket_index], strlen(info) - bracket_index - 1); 43 | 44 | for (NSUInteger i = 0; i < strlen(info); i++) { 45 | if (after_bracket[i] == ' ') { 46 | after_bracket[i] = '\0'; 47 | } 48 | } 49 | 50 | return objc_getClass(after_bracket); 51 | } 52 | 53 | // takes __PRETTY_FUNCTION__ for info which gives the name of the swizzle source class 54 | /* 55 | 56 | We add the original implementation onto the swizzle class 57 | On ZKOrig, we use __PRETTY_FUNCTION__ to get the name of the swizzle class 58 | Then we get the implementation of that selector on the swizzle class 59 | Then we call it directly, passing in the correct selector and self 60 | 61 | */ 62 | ZKIMP ZKOriginalImplementation(id self, SEL sel, const char *info) { 63 | if (sel == NULL || self == NULL || info == NULL) { 64 | [NSException raise:@"Invalid Arguments" format:@"One of self: %@, self: %@, or info: %s is NULL", self, NSStringFromSelector(sel), info]; 65 | return NULL; 66 | } 67 | 68 | Class cls = classFromInfo(info); 69 | Class dest = object_getClass(self); 70 | 71 | if (cls == NULL || dest == NULL) { 72 | [NSException raise:@"Failed obtain class pair" format:@"src: %@ | dst: %@ | sel: %@", NSStringFromClass(cls), NSStringFromClass(dest), NSStringFromSelector(sel)]; 73 | return NULL; 74 | } 75 | 76 | SEL destSel = destinationSelectorForSelector(sel, cls); 77 | 78 | Method method = class_getInstanceMethod(dest, destSel); 79 | 80 | if (method == NULL) { 81 | [NSException raise:@"Failed to retrieve method" format:@"Got null for the source class %@ with selector %@ (%@)", NSStringFromClass(cls), NSStringFromSelector(sel), NSStringFromSelector(destSel)]; 82 | return NULL; 83 | } 84 | 85 | ZKIMP implementation = (ZKIMP)method_getImplementation(method); 86 | if (implementation == NULL) { 87 | [NSException raise:@"Failed to get implementation" format:@"The objective-c runtime could not get the implementation for %@ on the class %@. There is no fix for this", NSStringFromClass(cls), NSStringFromSelector(sel)]; 88 | } 89 | 90 | return implementation; 91 | } 92 | 93 | ZKIMP ZKSuperImplementation(id object, SEL sel, const char *info) { 94 | if (sel == NULL || object == NULL) { 95 | [NSException raise:@"Invalid Arguments" format:@"One of self: %@, self: %@ is NULL", object, NSStringFromSelector(sel)]; 96 | return NULL; 97 | } 98 | 99 | Class cls = object_getClass(object); 100 | if (cls == NULL) { 101 | [NSException raise:@"Invalid Argument" format:@"Could not obtain class for the passed object"]; 102 | return NULL; 103 | } 104 | 105 | // Two scenarios: 106 | // 1.) The superclass was not swizzled, no problem 107 | // 2.) The superclass was swizzled, problem 108 | 109 | // We want to return the swizzled class's superclass implementation 110 | // If this is a subclass of such a class, we want two behaviors: 111 | // a.) If this imp was also swizzled, no problem, return the superclass's swizzled imp 112 | // b.) This imp was not swizzled, return the class that was originally swizzled's superclass's imp 113 | Class sourceClass = classFromInfo(info); 114 | if (sourceClass != NULL) { 115 | BOOL isClassMethod = class_isMetaClass(cls); 116 | // This was called from a swizzled method, get the class it was swizzled with 117 | NSString *className = classTable[NSStringFromClass(sourceClass)]; 118 | if (className != NULL) { 119 | cls = NSClassFromString(className); 120 | // make sure we get a class method if we asked for one 121 | if (isClassMethod) { 122 | cls = object_getClass(cls); 123 | } 124 | } 125 | } 126 | 127 | cls = class_getSuperclass(cls); 128 | 129 | // This is a root class, it has no super class 130 | if (cls == NULL) { 131 | [NSException raise:@"Invalid Argument" format:@"Could not obtain superclass for the passed object"]; 132 | return NULL; 133 | } 134 | 135 | Method method = class_getInstanceMethod(cls, sel); 136 | if (method == NULL) { 137 | [NSException raise:@"Failed to retrieve method" format:@"We could not find the super implementation for the class %@ and selector %@, are you sure it exists?", NSStringFromClass(cls), NSStringFromSelector(sel)]; 138 | return NULL; 139 | } 140 | 141 | ZKIMP implementation = (ZKIMP)method_getImplementation(method); 142 | if (implementation == NULL) { 143 | [NSException raise:@"Failed to get implementation" format:@"The objective-c runtime could not get the implementation for %@ on the class %@. There is no fix for this", NSStringFromClass(cls), NSStringFromSelector(sel)]; 144 | } 145 | 146 | return implementation; 147 | } 148 | 149 | static BOOL enumerateMethods(Class, Class); 150 | BOOL _ZKSwizzle(Class src, Class dest) { 151 | if (dest == NULL) 152 | return NO; 153 | 154 | NSString *destName = NSStringFromClass(dest); 155 | if (!destName) { 156 | return NO; 157 | } 158 | 159 | if (!classTable) { 160 | classTable = [[NSMutableDictionary alloc] init]; 161 | } 162 | 163 | if ([classTable objectForKey:NSStringFromClass(src)]) { 164 | [NSException raise:@"Invalid Argument" 165 | format:@"This source class (%@) was already swizzled with another, (%@)", NSStringFromClass(src), classTable[NSStringFromClass(src)]]; 166 | return NO; 167 | } 168 | 169 | BOOL success = enumerateMethods(dest, src); 170 | // The above method only gets instance methods. Do the same method for the metaclass of the class 171 | success &= enumerateMethods(object_getClass(dest), object_getClass(src)); 172 | 173 | [classTable setObject:destName forKey:NSStringFromClass(src)]; 174 | return success; 175 | } 176 | 177 | BOOL _ZKSwizzleClass(Class cls) { 178 | return _ZKSwizzle(cls, [cls superclass]); 179 | } 180 | 181 | static BOOL classIgnoresTypes(Class cls) { 182 | if (!class_isMetaClass(cls)) { 183 | cls = object_getClass(cls); 184 | } 185 | 186 | if (class_respondsToSelector(cls, @selector(_ZK_ignoreTypes))) { 187 | Class cls2 = class_createInstance(cls, 0); 188 | return [cls2 _ZK_ignoreTypes]; 189 | } 190 | 191 | return NO; 192 | } 193 | 194 | static BOOL enumerateMethods(Class destination, Class source) { 195 | #if OBJC_API_VERSION < 2 196 | [NSException raise:@"Unsupported feature" format:@"ZKSwizzle is only available in objc 2.0"]; 197 | return NO; 198 | 199 | #else 200 | 201 | unsigned int methodCount; 202 | Method *methodList = class_copyMethodList(source, &methodCount); 203 | BOOL success = YES; 204 | BOOL ignoreTypes = classIgnoresTypes(source); 205 | 206 | for (int i = 0; i < methodCount; i++) { 207 | Method method = methodList[i]; 208 | SEL selector = method_getName(method); 209 | NSString *methodName = NSStringFromSelector(selector); 210 | 211 | // Don't do anything with the unconditional swizzle 212 | if (sel_isEqual(selector, @selector(_ZK_unconditionallySwizzle)) || 213 | sel_isEqual(selector, @selector(_ZK_ignoreTypes))) { 214 | continue; 215 | } 216 | 217 | // We only swizzle methods that are implemented 218 | if (class_respondsToSelector(destination, selector)) { 219 | Method originalMethod = class_getInstanceMethod(destination, selector); 220 | 221 | const char *originalType = method_getTypeEncoding(originalMethod); 222 | const char *newType = method_getTypeEncoding(method); 223 | if (strcmp(originalType, newType) != 0 && !ignoreTypes) { 224 | NSLog(@"ZKSwizzle: incompatible type encoding for %@. (expected %s, got %s)", methodName, originalType, newType); 225 | // Incompatible type encoding 226 | success = NO; 227 | continue; 228 | } 229 | 230 | // We are re-adding the destination selector because it could be on a superclass and not on the class itself. This method could fail 231 | class_addMethod(destination, selector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); 232 | 233 | SEL destSel = destinationSelectorForSelector(selector, source); 234 | if (!class_addMethod(destination, destSel, method_getImplementation(method), method_getTypeEncoding(originalMethod))) { 235 | NSLog(@"ZKSwizzle: failed to add method %@ onto class %@ with selector %@", NSStringFromSelector(selector), NSStringFromClass(source), NSStringFromSelector(destSel)); 236 | success = NO; 237 | continue; 238 | } 239 | 240 | method_exchangeImplementations(class_getInstanceMethod(destination, selector), class_getInstanceMethod(destination, destSel)); 241 | } else { 242 | // Add any extra methods to the class but don't swizzle them 243 | success &= class_addMethod(destination, selector, method_getImplementation(method), method_getTypeEncoding(method)); 244 | } 245 | } 246 | 247 | unsigned int propertyCount; 248 | objc_property_t *propertyList = class_copyPropertyList(source, &propertyCount); 249 | for (int i = 0; i < propertyCount; i++) { 250 | objc_property_t property = propertyList[i]; 251 | const char *name = property_getName(property); 252 | unsigned int attributeCount; 253 | objc_property_attribute_t *attributes = property_copyAttributeList(property, &attributeCount); 254 | 255 | if (class_getProperty(destination, name) == NULL) { 256 | class_addProperty(destination, name, attributes, attributeCount); 257 | } else { 258 | class_replaceProperty(destination, name, attributes, attributeCount); 259 | } 260 | 261 | free(attributes); 262 | } 263 | 264 | free(propertyList); 265 | free(methodList); 266 | return success; 267 | #endif 268 | } 269 | 270 | // Options were to use a group class and traverse its subclasses 271 | // or to create a groups dictionary 272 | // This works because +load on NSObject is called before attribute((constructor)) 273 | static NSMutableDictionary *groups = nil; 274 | void _$ZKRegisterInterface(Class cls, const char *groupName) { 275 | if (!groups) 276 | groups = [[NSMutableDictionary dictionary] retain]; 277 | 278 | NSString *groupString = @(groupName); 279 | NSMutableArray *groupList = groups[groupString]; 280 | if (!groupList) { 281 | groupList = [NSMutableArray array]; 282 | groups[groupString] = groupList; 283 | } 284 | 285 | [groupList addObject:NSStringFromClass(cls)]; 286 | } 287 | 288 | BOOL _ZKSwizzleGroup(const char *groupName) { 289 | NSArray *groupList = groups[@(groupName)]; 290 | if (!groupList) { 291 | [NSException raise:@"Invalid Argument" format:@"ZKSwizzle: There is no group by the name of %s", groupName]; 292 | return NO; 293 | } 294 | 295 | BOOL success = YES; 296 | for (NSString *className in groupList) { 297 | Class cls = NSClassFromString(className); 298 | if (cls == NULL) 299 | continue; 300 | 301 | if (class_respondsToSelector(object_getClass(cls), @selector(_ZK_unconditionallySwizzle))) { 302 | [cls _ZK_unconditionallySwizzle]; 303 | } else { 304 | success = NO; 305 | } 306 | } 307 | 308 | return success; 309 | } 310 | -------------------------------------------------------------------------------- /templates/Example Plugin/template/bundle.m: -------------------------------------------------------------------------------- 1 | // 2 | // bundle.m 3 | // template 4 | // 5 | // Created by Wolfgang Baird on 8/15/16. 6 | // Copyright © 2019 Wolfgang Baird. All rights reserved. 7 | // 8 | 9 | /* 10 | 11 | Really simple starting point for an OSX SIMBL Plugin 12 | 13 | */ 14 | 15 | // Imports & Includes 16 | @import AppKit; 17 | #include "ZKSwizzle.h" 18 | 19 | // Interfaces 20 | @interface bundle : NSObject 21 | @end 22 | 23 | // Variables 24 | bundle *plugin; 25 | NSInteger osx_ver; 26 | 27 | // Implementation 28 | @implementation bundle 29 | 30 | /* 31 | 32 | Usefull for if you're going to reference a method or something in the plugin 33 | 34 | EG: 35 | 36 | plugin = [bundle sharedInstance]; 37 | [plugin doStuff]; 38 | 39 | */ 40 | + (bundle*) sharedInstance 41 | { 42 | static bundle* plugin = nil; 43 | if (plugin == nil) 44 | plugin = [[bundle alloc] init]; 45 | return plugin; 46 | } 47 | 48 | /* 49 | 50 | Initial setup. Usually here I detemine if the plugin should load by checking macOS version and or a blacklist/whitelist of bundle IDs. 51 | Good idea to log that your plugin has loaded at the end. 52 | 53 | */ 54 | 55 | + (void)load { 56 | plugin = [bundle sharedInstance]; 57 | osx_ver = [[NSProcessInfo processInfo] operatingSystemVersion].minorVersion; 58 | 59 | /* A basic swizzle */ 60 | // ZKSwizzle(swizzleMethod, NSObject); 61 | 62 | NSLog(@"OS X 10.%ld, %@ loaded...", (long)osx_ver, [self class]); 63 | } 64 | 65 | @end 66 | 67 | 68 | /* An example swizzle 69 | 70 | @interface swizzleMethod : NSObject 71 | @end 72 | 73 | @implementation swizzleMethod 74 | 75 | - (BOOL)someMethod { 76 | return YES; 77 | } 78 | 79 | @end 80 | 81 | */ 82 | -------------------------------------------------------------------------------- /templates/Xcode Template/MacForge Plugin.xctemplate/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | $(PRODUCT_BUNDLE_IDENTIFIER) 7 | CFBundleDevelopmentRegion 8 | English 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleName 12 | $(PRODUCT_NAME) 13 | CFBundleIconFile 14 | 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundlePackageType 18 | BNDL 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | CFBundleShortVersionString 24 | 1.0 25 | NSPrincipalClass 26 | ___PACKAGENAME___ 27 | SIMBLTargetApplications 28 | 29 | 30 | BundleIdentifier 31 | ___VARIABLE_SimblTargetAppBundleId___ 32 | MinBundleVersion 33 | 0 34 | MaxBundleVersion 35 | 999999999 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /templates/Xcode Template/MacForge Plugin.xctemplate/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // ___FILENAME___ 3 | // ___PROJECTNAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #ifndef ___PACKAGENAME____PrefixHeader_pch 10 | #define ___PACKAGENAME____PrefixHeader_pch 11 | 12 | #import 13 | #import "ZKSwizzle.h" 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /templates/Xcode Template/MacForge Plugin.xctemplate/TemplateIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/w0lfschild/macplugins/bf8730d862b04834b3041bea2452035865b3cf5c/templates/Xcode Template/MacForge Plugin.xctemplate/TemplateIcon.icns -------------------------------------------------------------------------------- /templates/Xcode Template/MacForge Plugin.xctemplate/TemplateInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Kind 6 | Xcode.Xcode3.ProjectTemplateUnitKind 7 | Identifier 8 | com.macenhance.samplebundle 9 | Concrete 10 | 11 | Description 12 | This template builds an EasySIMBL bundle. 13 | Platforms 14 | 15 | com.apple.platform.macosx 16 | 17 | Ancestors 18 | 19 | com.apple.dt.unit.bundleBase 20 | com.apple.dt.unit.macBase 21 | 22 | Targets 23 | 24 | 25 | ProductType 26 | com.apple.product-type.bundle 27 | Frameworks 28 | 29 | AppKit 30 | Foundation 31 | 32 | SharedSettings 33 | 34 | DEPLOYMENT_LOCATION 35 | YES 36 | DSTROOT 37 | / 38 | INSTALL_PATH 39 | /Library/Application Support/MacEnhance/Plugins 40 | WRAPPER_EXTENSION 41 | bundle 42 | MACH_O_TYPE 43 | mh_dylib 44 | COMBINE_HIDPI_IMAGES 45 | YES 46 | GCC_PRECOMPILE_PREFIX_HEADER 47 | YES 48 | GCC_PREFIX_HEADER 49 | ___PACKAGENAME___/PrefixHeader.pch 50 | ARCHS 51 | $(ARCHS_STANDARD) 52 | CLANG_ENABLE_OBJC_ARC 53 | YES 54 | 55 | BuildPhases 56 | 57 | 58 | Class 59 | Sources 60 | 61 | 62 | Class 63 | Frameworks 64 | 65 | 66 | Class 67 | Resources 68 | 69 | 70 | 71 | 72 | Options 73 | 74 | 75 | Identifier 76 | SimblTargetAppBundleId 77 | Name 78 | Target App Bundle Id: 79 | Description 80 | Target App Bundle Id. 81 | Type 82 | text 83 | Placeholder 84 | com.apple.appstore 85 | 86 | 87 | Nodes 88 | 89 | ___PACKAGENAME___.h 90 | ___PACKAGENAME___.m 91 | ZKSwizzle/ZKSwizzle.h 92 | ZKSwizzle/ZKSwizzle.m 93 | PrefixHeader.pch 94 | Info.plist 95 | 96 | Definitions 97 | 98 | ___PACKAGENAME___.h 99 | 100 | Path 101 | ___PACKAGENAME___.h 102 | 103 | ___PACKAGENAME___.m 104 | 105 | Path 106 | ___PACKAGENAME___.m 107 | 108 | ZKSwizzle/ZKSwizzle.h 109 | 110 | Group 111 | 112 | ZKSwizzle 113 | 114 | Path 115 | ZKSwizzle/ZKSwizzle.h 116 | 117 | ZKSwizzle/ZKSwizzle.m 118 | 119 | Group 120 | 121 | ZKSwizzle 122 | 123 | Path 124 | ZKSwizzle/ZKSwizzle.m 125 | 126 | PrefixHeader.pch 127 | 128 | Group 129 | 130 | Supporting Files 131 | 132 | Path 133 | PrefixHeader.pch 134 | 135 | Info.plist 136 | 137 | Group 138 | 139 | Supporting Files 140 | 141 | Path 142 | Info.plist 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /templates/Xcode Template/MacForge Plugin.xctemplate/ZKSwizzle/ZKSwizzle.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZKSwizzle.h 3 | // ZKSwizzle 4 | // 5 | // Created by Alexander S Zielenski on 7/24/14. 6 | // Copyright (c) 2014 Alexander S Zielenski. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | // This is a class for streamlining swizzling. Simply create a new class of any name you want and 14 | // Example: 15 | /* 16 | @interface ZKHookClass : NSObject 17 | - (NSString *)description; // hooks -description on NSObject 18 | - (void)addedMethod; // all subclasses of NSObject now respond to -addedMethod 19 | @end 20 | 21 | @implementation ZKHookClass 22 | ... 23 | @end 24 | 25 | [ZKSwizzle swizzleClass:ZKClass(ZKHookClass) forClass:ZKClass(destination)]; 26 | */ 27 | 28 | #ifndef ZKSWIZZLE_DEFS 29 | #define ZKSWIZZLE_DEFS 30 | 31 | // CRAZY MACROS FOR DYNAMIC PROTOTYPE CREATION 32 | #define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(0, ## __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5 ,4 ,3 ,2, 1, 0) 33 | #define VA_NUM_ARGS_IMPL(_0, _1,_2,_3,_4,_5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20 ,N,...) N 34 | 35 | #define WRAP0() 36 | #define WRAP1(VARIABLE) , typeof ( VARIABLE ) 37 | #define WRAP2(VARIABLE, ...) WRAP1(VARIABLE) WRAP1(__VA_ARGS__) 38 | #define WRAP3(VARIABLE, ...) WRAP1(VARIABLE) WRAP2(__VA_ARGS__) 39 | #define WRAP4(VARIABLE, ...) WRAP1(VARIABLE) WRAP3(__VA_ARGS__) 40 | #define WRAP5(VARIABLE, ...) WRAP1(VARIABLE) WRAP4(__VA_ARGS__) 41 | #define WRAP6(VARIABLE, ...) WRAP1(VARIABLE) WRAP5(__VA_ARGS__) 42 | #define WRAP7(VARIABLE, ...) WRAP1(VARIABLE) WRAP6(__VA_ARGS__) 43 | #define WRAP8(VARIABLE, ...) WRAP1(VARIABLE) WRAP7(__VA_ARGS__) 44 | #define WRAP9(VARIABLE, ...) WRAP1(VARIABLE) WRAP8(__VA_ARGS__) 45 | #define WRAP10(VARIABLE, ...) WRAP1(VARIABLE) WRAP9(__VA_ARGS__) 46 | #define WRAP11(VARIABLE, ...) WRAP1(VARIABLE) WRAP10(__VA_ARGS__) 47 | #define WRAP12(VARIABLE, ...) WRAP1(VARIABLE) WRAP11(__VA_ARGS__) 48 | #define WRAP13(VARIABLE, ...) WRAP1(VARIABLE) WRAP12(__VA_ARGS__) 49 | #define WRAP14(VARIABLE, ...) WRAP1(VARIABLE) WRAP13(__VA_ARGS__) 50 | #define WRAP15(VARIABLE, ...) WRAP1(VARIABLE) WRAP14(__VA_ARGS__) 51 | #define WRAP16(VARIABLE, ...) WRAP1(VARIABLE) WRAP15(__VA_ARGS__) 52 | #define WRAP17(VARIABLE, ...) WRAP1(VARIABLE) WRAP16(__VA_ARGS__) 53 | #define WRAP18(VARIABLE, ...) WRAP1(VARIABLE) WRAP17(__VA_ARGS__) 54 | #define WRAP19(VARIABLE, ...) WRAP1(VARIABLE) WRAP18(__VA_ARGS__) 55 | #define WRAP20(VARIABLE, ...) WRAP1(VARIABLE) WRAP19(__VA_ARGS__) 56 | 57 | #define CAT(A, B) A ## B 58 | #define INVOKE(MACRO, NUMBER, ...) CAT(MACRO, NUMBER)(__VA_ARGS__) 59 | #define WRAP_LIST(...) INVOKE(WRAP, VA_NUM_ARGS(__VA_ARGS__), __VA_ARGS__) 60 | 61 | // Gets the a class with the name CLASS 62 | #define ZKClass(CLASS) objc_getClass(#CLASS) 63 | 64 | // returns the value of an instance variable. 65 | #if !__has_feature(objc_arc) 66 | #define ZKHookIvar(OBJECT, TYPE, NAME) (*(TYPE *)ZKIvarPointer(OBJECT, NAME)) 67 | #else 68 | #define ZKHookIvar(OBJECT, TYPE, NAME) \ 69 | _Pragma("clang diagnostic push") \ 70 | _Pragma("clang diagnostic ignored \"-Wignored-attributes\"") \ 71 | (*(__unsafe_unretained TYPE *)ZKIvarPointer(OBJECT, NAME)) \ 72 | _Pragma("clang diagnostic pop") 73 | #endif 74 | // returns the original implementation of the swizzled function or null or not found 75 | #define ZKOrig(TYPE, ...) ((TYPE (*)(id, SEL WRAP_LIST(__VA_ARGS__)))(ZKOriginalImplementation(self, _cmd, __PRETTY_FUNCTION__)))(self, _cmd, ##__VA_ARGS__) 76 | 77 | // returns the original implementation of the superclass of the object swizzled 78 | #define ZKSuper(TYPE, ...) ((TYPE (*)(id, SEL WRAP_LIST(__VA_ARGS__)))(ZKSuperImplementation(self, _cmd, __PRETTY_FUNCTION__)))(self, _cmd, ##__VA_ARGS__) 79 | 80 | #define _ZKSwizzleInterfaceConditionally(CLASS_NAME, TARGET_CLASS, SUPERCLASS, GROUP, IMMEDIATELY) \ 81 | @interface _$ ## CLASS_NAME : SUPERCLASS @end \ 82 | @implementation _$ ## CLASS_NAME \ 83 | + (void)initialize {} \ 84 | @end \ 85 | @interface CLASS_NAME : _$ ## CLASS_NAME @end \ 86 | @implementation CLASS_NAME (ZKSWIZZLE) \ 87 | + (void)load { \ 88 | _$ZKRegisterInterface(self, #GROUP);\ 89 | if (IMMEDIATELY) { \ 90 | [self _ZK_unconditionallySwizzle]; \ 91 | } \ 92 | } \ 93 | + (void)_ZK_unconditionallySwizzle { \ 94 | ZKSwizzle(CLASS_NAME, TARGET_CLASS); \ 95 | } \ 96 | @end 97 | 98 | // Bootstraps your swizzling class so that it requires no setup 99 | // outside of this macro call 100 | // If you override +load you must call ZKSwizzle(CLASS_NAME, TARGET_CLASS) 101 | // yourself, otherwise the swizzling would not take place 102 | #define ZKSwizzleInterface(CLASS_NAME, TARGET_CLASS, SUPERCLASS) \ 103 | _ZKSwizzleInterfaceConditionally(CLASS_NAME, TARGET_CLASS, SUPERCLASS, ZK_UNGROUPED, YES) 104 | 105 | // Same as ZKSwizzleInterface, except 106 | #define ZKSwizzleInterfaceGroup(CLASS_NAME, TARGET_CLASS, SUPER_CLASS, GROUP) \ 107 | _ZKSwizzleInterfaceConditionally(CLASS_NAME, TARGET_CLASS, SUPER_CLASS, GROUP, NO) 108 | 109 | __BEGIN_DECLS 110 | 111 | // Make sure to cast this before you use it 112 | typedef id (*ZKIMP)(id, SEL, ...); 113 | 114 | // returns a pointer to the instance variable "name" on the object 115 | void *ZKIvarPointer(id self, const char *name); 116 | // returns the original implementation of a method with selector "sel" of an object hooked by the methods below 117 | ZKIMP ZKOriginalImplementation(id self, SEL sel, const char *info); 118 | // returns the implementation of a method with selector "sel" of the superclass of object 119 | ZKIMP ZKSuperImplementation(id object, SEL sel, const char *info); 120 | 121 | // hooks all the implemented methods of source with destination 122 | // adds any methods that arent implemented on destination to destination that are implemented in source 123 | #define ZKSwizzle(src, dst) _ZKSwizzle(ZKClass(src), ZKClass(dst)) 124 | BOOL _ZKSwizzle(Class src, Class dest); 125 | 126 | #define ZKSwizzleGroup(NAME) _ZKSwizzleGroup(#NAME) 127 | void _$ZKRegisterInterface(Class cls, const char *groupName); 128 | BOOL _ZKSwizzleGroup(const char *groupName); 129 | 130 | // Calls above method with the superclass of source for desination 131 | #define ZKSwizzleClass(src) _ZKSwizzleClass(ZKClass(src)) 132 | BOOL _ZKSwizzleClass(Class cls); 133 | 134 | __END_DECLS 135 | #endif 136 | 137 | -------------------------------------------------------------------------------- /templates/Xcode Template/MacForge Plugin.xctemplate/ZKSwizzle/ZKSwizzle.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZKSwizzle.m 3 | // ZKSwizzle 4 | // 5 | // Created by Alexander S Zielenski on 7/24/14. 6 | // Copyright (c) 2014 Alexander S Zielenski. All rights reserved. 7 | // 8 | 9 | #import "ZKSwizzle.h" 10 | static NSMutableDictionary *classTable; 11 | 12 | @interface NSObject (ZKSwizzle) 13 | + (void)_ZK_unconditionallySwizzle; 14 | @end 15 | 16 | void *ZKIvarPointer(id self, const char *name) { 17 | Ivar ivar = class_getInstanceVariable(object_getClass(self), name); 18 | return ivar == NULL ? NULL : (__bridge void *)self + ivar_getOffset(ivar); 19 | } 20 | 21 | static SEL destinationSelectorForSelector(SEL cmd, Class dst) { 22 | return NSSelectorFromString([@"_ZK_old_" stringByAppendingFormat:@"%s_%@", class_getName(dst), NSStringFromSelector(cmd)]); 23 | } 24 | 25 | static Class classFromInfo(const char *info) { 26 | NSUInteger bracket_index = -1; 27 | for (NSUInteger i = 0; i < strlen(info); i++) { 28 | if (info[i] == '[') { 29 | bracket_index = i; 30 | } 31 | } 32 | bracket_index++; 33 | 34 | if (bracket_index == -1) { 35 | [NSException raise:@"Failed to parse info" format:@"Couldn't find swizzle class for info: %s", info]; 36 | return NULL; 37 | } 38 | 39 | char after_bracket[255]; 40 | memcpy(after_bracket, &info[bracket_index], strlen(info) - bracket_index - 1); 41 | 42 | for (NSUInteger i = 0; i < strlen(info); i++) { 43 | if (after_bracket[i] == ' ') { 44 | after_bracket[i] = '\0'; 45 | } 46 | } 47 | 48 | return objc_getClass(after_bracket); 49 | } 50 | 51 | // takes __PRETTY_FUNCTION__ for info which gives the name of the swizzle source class 52 | /* 53 | 54 | We add the original implementation onto the swizzle class 55 | On ZKOrig, we use __PRETTY_FUNCTION__ to get the name of the swizzle class 56 | Then we get the implementation of that selector on the swizzle class 57 | Then we call it directly, passing in the correct selector and self 58 | 59 | */ 60 | ZKIMP ZKOriginalImplementation(id self, SEL sel, const char *info) { 61 | if (sel == NULL || self == NULL || info == NULL) { 62 | [NSException raise:@"Invalid Arguments" format:@"One of self: %@, self: %@, or info: %s is NULL", self, NSStringFromSelector(sel), info]; 63 | return NULL; 64 | } 65 | 66 | Class cls = classFromInfo(info); 67 | Class dest = object_getClass(self); 68 | 69 | if (cls == NULL || dest == NULL) { 70 | [NSException raise:@"Failed obtain class pair" format:@"src: %@ | dst: %@ | sel: %@", NSStringFromClass(cls), NSStringFromClass(dest), NSStringFromSelector(sel)]; 71 | return NULL; 72 | } 73 | 74 | SEL destSel = destinationSelectorForSelector(sel, cls); 75 | 76 | Method method = class_getInstanceMethod(dest, destSel); 77 | 78 | if (method == NULL) { 79 | [NSException raise:@"Failed to retrieve method" format:@"Got null for the source class %@ with selector %@ (%@)", NSStringFromClass(cls), NSStringFromSelector(sel), NSStringFromSelector(destSel)]; 80 | return NULL; 81 | } 82 | 83 | ZKIMP implementation = (ZKIMP)method_getImplementation(method); 84 | if (implementation == NULL) { 85 | [NSException raise:@"Failed to get implementation" format:@"The objective-c runtime could not get the implementation for %@ on the class %@. There is no fix for this", NSStringFromClass(cls), NSStringFromSelector(sel)]; 86 | } 87 | 88 | return implementation; 89 | } 90 | 91 | ZKIMP ZKSuperImplementation(id object, SEL sel, const char *info) { 92 | if (sel == NULL || object == NULL) { 93 | [NSException raise:@"Invalid Arguments" format:@"One of self: %@, self: %@ is NULL", object, NSStringFromSelector(sel)]; 94 | return NULL; 95 | } 96 | 97 | Class cls = object_getClass(object); 98 | if (cls == NULL) { 99 | [NSException raise:@"Invalid Argument" format:@"Could not obtain class for the passed object"]; 100 | return NULL; 101 | } 102 | 103 | // Two scenarios: 104 | // 1.) The superclass was not swizzled, no problem 105 | // 2.) The superclass was swizzled, problem 106 | 107 | // We want to return the swizzled class's superclass implementation 108 | // If this is a subclass of such a class, we want two behaviors: 109 | // a.) If this imp was also swizzled, no problem, return the superclass's swizzled imp 110 | // b.) This imp was not swizzled, return the class that was originally swizzled's superclass's imp 111 | Class sourceClass = classFromInfo(info); 112 | if (sourceClass != NULL) { 113 | BOOL isClassMethod = class_isMetaClass(cls); 114 | // This was called from a swizzled method, get the class it was swizzled with 115 | NSString *className = classTable[NSStringFromClass(sourceClass)]; 116 | if (className != NULL) { 117 | cls = NSClassFromString(className); 118 | // make sure we get a class method if we asked for one 119 | if (isClassMethod) { 120 | cls = object_getClass(cls); 121 | } 122 | } 123 | } 124 | 125 | cls = class_getSuperclass(cls); 126 | 127 | // This is a root class, it has no super class 128 | if (cls == NULL) { 129 | [NSException raise:@"Invalid Argument" format:@"Could not obtain superclass for the passed object"]; 130 | return NULL; 131 | } 132 | 133 | Method method = class_getInstanceMethod(cls, sel); 134 | if (method == NULL) { 135 | [NSException raise:@"Failed to retrieve method" format:@"We could not find the super implementation for the class %@ and selector %@, are you sure it exists?", NSStringFromClass(cls), NSStringFromSelector(sel)]; 136 | return NULL; 137 | } 138 | 139 | ZKIMP implementation = (ZKIMP)method_getImplementation(method); 140 | if (implementation == NULL) { 141 | [NSException raise:@"Failed to get implementation" format:@"The objective-c runtime could not get the implementation for %@ on the class %@. There is no fix for this", NSStringFromClass(cls), NSStringFromSelector(sel)]; 142 | } 143 | 144 | return implementation; 145 | } 146 | 147 | static BOOL enumerateMethods(Class, Class); 148 | BOOL _ZKSwizzle(Class src, Class dest) { 149 | if (dest == NULL) 150 | return NO; 151 | 152 | NSString *destName = NSStringFromClass(dest); 153 | if (!destName) { 154 | return NO; 155 | } 156 | 157 | if (!classTable) { 158 | classTable = [[NSMutableDictionary alloc] init]; 159 | } 160 | 161 | if ([classTable objectForKey:NSStringFromClass(src)]) { 162 | [NSException raise:@"Invalid Argument" 163 | format:@"This source class (%@) was already swizzled with another, (%@)", NSStringFromClass(src), classTable[NSStringFromClass(src)]]; 164 | return NO; 165 | } 166 | 167 | BOOL success = enumerateMethods(dest, src); 168 | // The above method only gets instance methods. Do the same method for the metaclass of the class 169 | success &= enumerateMethods(object_getClass(dest), object_getClass(src)); 170 | 171 | [classTable setObject:destName forKey:NSStringFromClass(src)]; 172 | return success; 173 | } 174 | 175 | BOOL _ZKSwizzleClass(Class cls) { 176 | return _ZKSwizzle(cls, [cls superclass]); 177 | } 178 | 179 | static BOOL enumerateMethods(Class destination, Class source) { 180 | #if OBJC_API_VERSION < 2 181 | [NSException raise:@"Unsupported feature" format:@"ZKSwizzle is only available in objc 2.0"]; 182 | return NO; 183 | 184 | #else 185 | 186 | unsigned int methodCount; 187 | Method *methodList = class_copyMethodList(source, &methodCount); 188 | BOOL success = YES; 189 | for (int i = 0; i < methodCount; i++) { 190 | Method method = methodList[i]; 191 | SEL selector = method_getName(method); 192 | NSString *methodName = NSStringFromSelector(selector); 193 | 194 | // Don't do anything with the unconditional swizzle 195 | if (sel_isEqual(selector, @selector(_ZK_unconditionallySwizzle))) { 196 | continue; 197 | } 198 | 199 | // We only swizzle methods that are implemented 200 | if (class_respondsToSelector(destination, selector)) { 201 | Method originalMethod = class_getInstanceMethod(destination, selector); 202 | 203 | const char *originalType = method_getTypeEncoding(originalMethod); 204 | const char *newType = method_getTypeEncoding(method); 205 | if (strcmp(originalType, newType) != 0) { 206 | NSLog(@"ZKSwizzle: incompatible type encoding for %@. (expected %s, got %s)", methodName, originalType, newType); 207 | // Incompatible type encoding 208 | success = NO; 209 | continue; 210 | } 211 | 212 | // We are re-adding the destination selector because it could be on a superclass and not on the class itself. This method could fail 213 | class_addMethod(destination, selector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); 214 | 215 | SEL destSel = destinationSelectorForSelector(selector, source); 216 | if (!class_addMethod(destination, destSel, method_getImplementation(method), method_getTypeEncoding(originalMethod))) { 217 | NSLog(@"ZKSwizzle: failed to add method %@ onto class %@ with selector %@", NSStringFromSelector(selector), NSStringFromClass(source), NSStringFromSelector(destSel)); 218 | success = NO; 219 | continue; 220 | } 221 | 222 | method_exchangeImplementations(class_getInstanceMethod(destination, selector), class_getInstanceMethod(destination, destSel)); 223 | } else { 224 | // Add any extra methods to the class but don't swizzle them 225 | success &= class_addMethod(destination, selector, method_getImplementation(method), method_getTypeEncoding(method)); 226 | } 227 | } 228 | 229 | unsigned int propertyCount; 230 | objc_property_t *propertyList = class_copyPropertyList(source, &propertyCount); 231 | for (int i = 0; i < propertyCount; i++) { 232 | objc_property_t property = propertyList[i]; 233 | const char *name = property_getName(property); 234 | unsigned int attributeCount; 235 | objc_property_attribute_t *attributes = property_copyAttributeList(property, &attributeCount); 236 | 237 | if (class_getProperty(destination, name) == NULL) { 238 | class_addProperty(destination, name, attributes, attributeCount); 239 | } else { 240 | class_replaceProperty(destination, name, attributes, attributeCount); 241 | } 242 | 243 | free(attributes); 244 | } 245 | 246 | free(propertyList); 247 | free(methodList); 248 | return success; 249 | #endif 250 | } 251 | 252 | // Options were to use a group class and traverse its subclasses 253 | // or to create a groups dictionary 254 | // This works because +load on NSObject is called before attribute((constructor)) 255 | static NSMutableDictionary *groups = nil; 256 | void _$ZKRegisterInterface(Class cls, const char *groupName) { 257 | if (!groups) 258 | groups = [NSMutableDictionary dictionary]; 259 | 260 | NSString *groupString = @(groupName); 261 | NSMutableArray *groupList = groups[groupString]; 262 | if (!groupList) { 263 | groupList = [NSMutableArray array]; 264 | groups[groupString] = groupList; 265 | } 266 | 267 | [groupList addObject:NSStringFromClass(cls)]; 268 | } 269 | 270 | BOOL _ZKSwizzleGroup(const char *groupName) { 271 | NSArray *groupList = groups[@(groupName)]; 272 | if (!groupList) { 273 | [NSException raise:@"Invalid Argument" format:@"ZKSwizzle: There is no group by the name of %s", groupName]; 274 | return NO; 275 | } 276 | 277 | BOOL success = YES; 278 | for (NSString *className in groupList) { 279 | Class cls = NSClassFromString(className); 280 | if (cls == NULL) 281 | continue; 282 | 283 | if (class_respondsToSelector(object_getClass(cls), @selector(_ZK_unconditionallySwizzle))) { 284 | [cls _ZK_unconditionallySwizzle]; 285 | } else { 286 | success = NO; 287 | } 288 | } 289 | 290 | return success; 291 | } 292 | -------------------------------------------------------------------------------- /templates/Xcode Template/MacForge Plugin.xctemplate/___PACKAGENAME___.h: -------------------------------------------------------------------------------- 1 | // 2 | // ___PACKAGENAME___.h 3 | // ___PACKAGENAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import 10 | 11 | @interface ___PACKAGENAME___ : NSObject 12 | 13 | + (instancetype)sharedInstance; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /templates/Xcode Template/MacForge Plugin.xctemplate/___PACKAGENAME___.m: -------------------------------------------------------------------------------- 1 | // 2 | // ___PACKAGENAME___.m 3 | // ___PACKAGENAME___ 4 | // 5 | // Created by ___FULLUSERNAME___ on ___DATE___. 6 | //___COPYRIGHT___ 7 | // 8 | 9 | #import "___PACKAGENAME___.h" 10 | 11 | @interface ___PACKAGENAME___() 12 | 13 | @end 14 | 15 | 16 | @implementation ___PACKAGENAME___ 17 | 18 | /** 19 | * @return the single static instance of the plugin object 20 | */ 21 | + (instancetype)sharedInstance 22 | { 23 | static ___PACKAGENAME___ *plugin = nil; 24 | @synchronized(self) { 25 | if (!plugin) { 26 | plugin = [[self alloc] init]; 27 | } 28 | } 29 | return plugin; 30 | } 31 | 32 | 33 | /** 34 | * A special method called by SIMBL once the application has started and all classes are initialized. 35 | */ 36 | + (void)load 37 | { 38 | ___PACKAGENAME___ *plugin = [___PACKAGENAME___ sharedInstance]; 39 | NSUInteger osx_ver = [[NSProcessInfo processInfo] operatingSystemVersion].minorVersion; 40 | NSLog(@"%@ loaded into %@ on macOS 10.%ld", [self class], [[NSBundle mainBundle] bundleIdentifier], (long)osx_ver); 41 | } 42 | 43 | 44 | @end 45 | --------------------------------------------------------------------------------