├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── bluetooth ├── LICENSE ├── Makefile ├── README.md ├── bluetooth-v0.2.1-universal.tar.gz ├── init.lua └── internal.m ├── cgsdebug ├── LICENSE ├── Makefile ├── README.md ├── cgsdebug.h ├── init.lua └── internal.m ├── coredock ├── LICENSE ├── Makefile ├── README.md ├── coredock-v0.1.1-universal.tar.gz ├── coredock.h ├── init.lua └── internal.m └── cursor ├── CGSConnection.h ├── CGSCursor.h ├── LICENSE ├── Makefile ├── init.lua └── internal.m /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore these at the top level only 2 | Makefile 3 | __* 4 | objc2 5 | replacements 6 | 7 | # ignore in sub-directories as well 8 | 9 | **/*.dSYM/ 10 | **/*.so 11 | **/.gitignore 12 | **/.git 13 | **/tmp/ 14 | 15 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "spaces"] 2 | path = spaces 3 | url = https://github.com/asmagill/hs._asm.undocumented.spaces.git 4 | [submodule "touchbar"] 5 | path = touchbar 6 | url = https://github.com/asmagill/hs._asm.undocumented.touchbar.git 7 | [submodule "touchdevice"] 8 | path = touchdevice 9 | url = https://github.com/asmagill/hs._asm.undocumented.touchdevice.git 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Aaron Magill 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | _asm.undocumented 2 | ================= 3 | 4 | **Over the course of the next few months, I anticipate either archiving most of these or moving them into the https://github.com/asmagill/hammerspoon_asm umbrella. With the exception of the bluetooth, touchbar, and touchdevice modules, most of this is outdated enough that it either doesn't work or at least doesn't work well. I expect that it may be of some limited informational use, but no further maintenance is expected except for the three already listed.** 5 | 6 | - - - 7 | 8 | Organizational space for Hammerspoon modules using undocumented or Private APIs. 9 | 10 | Any module I knowingly create which uses any undocumented or private API will be listed here. For other modules, especially those which are not part of the core Hammerspoon application please check https://github.com/asmagill/hammerspoon_asm. 11 | 12 | Because they use undocumented features, the mantra "Caveat Emptor" rings even more true than usual. I make no claims or guarantees that these will work for you or that they will work with any past, present, or future version of OS X. All I will state is that they do not crash on my primary machine, a MacBook Air running 10.10.X, and that they provide at least some of the desired functions (or else why bother?) for me. 13 | 14 | I hope they work for you as well, but re-read the above paragraph and the License, and decide for yourself. 15 | 16 | ### Sub Modules (See folder README.md) 17 | The following submodules are located in this repository for organizational purposes. Installation instructions for each will be given in the appropriate subdirectory. 18 | 19 | |Module | Description | 20 | |:---------------------------|:------------------------------------------------------------------------------------| 21 | | hs._asm.undocumented.bluetooth | Toggle bluetooth power and discoverability. | 22 | | hs._asm.undocumented.cgsdebug | Includes Hydra's hydra.shadow function and other _windowserver debug stuff | 23 | | hs._asm.undocumented.coredock | Manipulate Dock features including position, tilesize, etc. | 24 | | [hs._asm.undocumented.spaces](https://github.com/asmagill/hs._asm.undocumented.spaces) | (Archived, for informational purposes only) | 25 | 26 | ### Installation 27 | 28 | *See https://github.com/asmagill/hammerspoon_asm/blob/master/README.md for details about building this module as a Universal library* 29 | 30 | Each sub-module has compilation instructions in the accompanying README file. Installing this way will ensure that you have the latest and greatest. 31 | 32 | At various points (i.e. when I feel like it or remember) I will add a precompiled release. These will most likely contain all of the modules currently in this repository unless otherwise noted in the release notes. You can always remove the ones you don't want, of course. 33 | 34 | Download the release from https://github.com/asmagill/hammerspoon_asm.undocumented/releases and issue the following commands: 35 | 36 | ~~~sh 37 | $ cd ~/.hammerspoon 38 | $ tar -xzf ~/Downloads/undocumented-vX.Y.tar.gz 39 | ~~~ 40 | 41 | If you are upgrading an existing version, remember to fully stop and restart Hammerspoon to insure that the new version is the one being used. 42 | 43 | ### Documentation 44 | 45 | For now, see the README.md in each folder. Since the Hammerspoon document system supports external sources, I hope to one day add that to the modules as well. 46 | 47 | ### More Information 48 | Most of the undocumented API information that is used within these modules I gleaned from one or more of the following sources: 49 | 50 | 1. [Undocumented Goodness](https://code.google.com/p/undocumented-goodness/) 51 | 2. [iTerm2's CGSInternal folder](https://github.com/gnachman/iterm2) 52 | 3. [NUIKit/CGSInternal](https://github.com/NUIKit/CGSInternal) 53 | 54 | ### License 55 | 56 | > Released under MIT license. 57 | > 58 | > Copyright (c) 2014 Aaron Magill 59 | > 60 | > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 61 | > 62 | > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 63 | > 64 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 65 | > 66 | -------------------------------------------------------------------------------- /bluetooth/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Aaron Magill 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /bluetooth/Makefile: -------------------------------------------------------------------------------- 1 | mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) 2 | current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) 3 | 4 | # Universal build info mostly from 5 | # https://developer.apple.com/documentation/xcode/building_a_universal_macos_binary 6 | # Insight on Universal dSYM from 7 | # https://lists.apple.com/archives/xcode-users/2009/Apr/msg00034.html 8 | 9 | MODULE := $(lastword $(subst ., ,$(current_dir))) 10 | PREFIX ?= ~/.hammerspoon 11 | MODPATH = hs/_asm/undocumented 12 | VERSION ?= 0.x 13 | HS_APPLICATION ?= /Applications 14 | 15 | # get from https://github.com/asmagill/hammerspoon-config/blob/master/utils/docmaker.lua 16 | # if you want to generate a readme file similar to the ones I generally use. Adjust the copyright in the file and adjust 17 | # this variable to match where you save docmaker.lua relative to your hammerspoon configuration directory 18 | # (usually ~/.hammerspoon) 19 | MARKDOWNMAKER = utils/docmaker.lua 20 | 21 | OBJCFILES = ${wildcard *.m} 22 | LUAFILES = ${wildcard *.lua} 23 | HEADERS = ${wildcard *.h} 24 | 25 | # for compiling each source file into a separate library 26 | # (see also obj_x86_64/%.s and obj_arm64/%.s below) 27 | SOFILES := $(OBJCFILES:.m=.so) 28 | 29 | # for compiling all source files into one library 30 | # (see also obj_x86_64/%.s and obj_arm64/%.s below) 31 | # SOFILES := internal.so 32 | 33 | SOFILES_x86_64 := $(addprefix obj_x86_64/,$(SOFILES)) 34 | SOFILES_arm64 := $(addprefix obj_arm64/,$(SOFILES)) 35 | SOFILES_univeral := $(addprefix obj_universal/,$(SOFILES)) 36 | 37 | DEBUG_CFLAGS ?= -g 38 | 39 | # special vars for uninstall 40 | space := 41 | space += 42 | comma := , 43 | ALLFILES := $(LUAFILES) 44 | ALLFILES += $(SOFILES) 45 | 46 | # CC=clang 47 | CC=@clang 48 | WARNINGS ?= -Weverything -Wno-objc-missing-property-synthesis -Wno-implicit-atomic-properties -Wno-direct-ivar-access -Wno-cstring-format-directive -Wno-padded -Wno-covered-switch-default -Wno-missing-prototypes -Werror-implicit-function-declaration -Wno-documentation-unknown-command -Wno-poison-system-directories 49 | EXTRA_CFLAGS ?= -F$(HS_APPLICATION)/Hammerspoon.app/Contents/Frameworks -DSOURCE_PATH="$(mkfile_path)" 50 | MIN_intel_VERSION ?= -mmacosx-version-min=10.13 51 | MIN_arm64_VERSION ?= -mmacosx-version-min=11 52 | 53 | CFLAGS += $(DEBUG_CFLAGS) -fmodules -fobjc-arc -DHS_EXTERNAL_MODULE $(WARNINGS) $(EXTRA_CFLAGS) 54 | release: CFLAGS += -DRELEASE_VERSION=$(VERSION) 55 | releaseWithDocs: CFLAGS += -DRELEASE_VERSION=$(VERSION) 56 | LDFLAGS += -dynamiclib -undefined dynamic_lookup $(EXTRA_LDFLAGS) 57 | 58 | all: verify $(shell uname -m) 59 | 60 | x86_64: $(SOFILES_x86_64) 61 | 62 | arm64: $(SOFILES_arm64) 63 | 64 | universal: verify x86_64 arm64 $(SOFILES_univeral) 65 | 66 | # for compiling each source file into a separate library 67 | # (see also SOFILES above) 68 | 69 | obj_x86_64/%.so: %.m $(HEADERS) 70 | $(CC) $< $(CFLAGS) $(MIN_intel_VERSION) $(LDFLAGS) -target x86_64-apple-macos10.13 -o $@ 71 | 72 | obj_arm64/%.so: %.m $(HEADERS) 73 | $(CC) $< $(CFLAGS) $(MIN_arm64_VERSION) $(LDFLAGS) -target arm64-apple-macos11 -o $@ 74 | 75 | # for compiling all source files into one library 76 | # (see also SOFILES above) 77 | 78 | # obj_x86_64/%.so: $(OBJCFILES) $(HEADERS) 79 | # $(CC) $(OBJCFILES) $(CFLAGS) $(MIN_intel_VERSION) $(LDFLAGS) -target x86_64-apple-macos10.13 -o $@ 80 | # 81 | # obj_arm64/%.so: $(OBJCFILES) $(HEADERS) 82 | # $(CC) $(OBJCFILES) $(CFLAGS) $(MIN_arm64_VERSION) $(LDFLAGS) -target arm64-apple-macos11 -o $@ 83 | 84 | # creating the universal dSYM bundle is a total hack because I haven't found a better 85 | # way yet... suggestions welcome 86 | obj_universal/%.so: $(SOFILES_x86_64) $(SOFILES_arm64) 87 | lipo -create -output $@ $(subst universal/,x86_64/,$@) $(subst universal/,arm64/,$@) 88 | mkdir -p $@.dSYM/Contents/Resources/DWARF/ 89 | cp $(subst universal/,x86_64/,$@).dSYM/Contents/Info.plist $@.dSYM/Contents 90 | lipo -create -output $@.dSYM/Contents/Resources/DWARF/$(subst obj_universal/,,$@) $(subst universal/,x86_64/,$@).dSYM/Contents/Resources/DWARF/$(subst obj_universal/,,$@) $(subst universal/,arm64/,$@).dSYM/Contents/Resources/DWARF/$(subst obj_universal/,,$@) 91 | 92 | $(SOFILES_x86_64): | obj_x86_64 93 | 94 | $(SOFILES_arm64): | obj_arm64 95 | 96 | $(SOFILES_univeral): | obj_universal 97 | 98 | obj_x86_64: 99 | mkdir obj_x86_64 100 | 101 | obj_arm64: 102 | mkdir obj_arm64 103 | 104 | obj_universal: 105 | mkdir obj_universal 106 | 107 | verify: $(LUAFILES) 108 | @if $$(hash lua >& /dev/null); then (luac -p $(LUAFILES) && echo "Lua Compile Verification Passed"); else echo "Skipping Lua Compile Verification"; fi 109 | 110 | install: install-$(shell uname -m) 111 | 112 | install-lua: $(LUAFILES) 113 | mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE) 114 | install -m 0644 $(LUAFILES) $(PREFIX)/$(MODPATH)/$(MODULE) 115 | test -f docs.json && install -m 0644 docs.json $(PREFIX)/$(MODPATH)/$(MODULE) || echo "No docs.json file to install" 116 | 117 | install-x86_64: verify install-lua $(SOFILES_x86_64) 118 | mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE) 119 | install -m 0644 $(SOFILES_x86_64) $(PREFIX)/$(MODPATH)/$(MODULE) 120 | cp -vpR $(SOFILES_x86_64:.so=.so.dSYM) $(PREFIX)/$(MODPATH)/$(MODULE) 121 | 122 | install-arm64: verify install-lua $(SOFILES_arm64) 123 | mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE) 124 | install -m 0644 $(SOFILES_arm64) $(PREFIX)/$(MODPATH)/$(MODULE) 125 | cp -vpR $(SOFILES_arm64:.so=.so.dSYM) $(PREFIX)/$(MODPATH)/$(MODULE) 126 | 127 | install-universal: verify install-lua $(SOFILES_univeral) 128 | mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE) 129 | install -m 0644 $(SOFILES_univeral) $(PREFIX)/$(MODPATH)/$(MODULE) 130 | cp -vpR $(SOFILES_univeral:.so=.so.dSYM) $(PREFIX)/$(MODPATH)/$(MODULE) 131 | 132 | uninstall: 133 | rm -v -f $(PREFIX)/$(MODPATH)/$(MODULE)/{$(subst $(space),$(comma),$(ALLFILES))} 134 | (pushd $(PREFIX)/$(MODPATH)/$(MODULE)/ ; rm -v -fr $(SOFILES:.so=.so.dSYM) ; popd) 135 | rm -v -f $(PREFIX)/$(MODPATH)/$(MODULE)/docs.json 136 | rmdir -p $(PREFIX)/$(MODPATH)/$(MODULE) ; exit 0 137 | 138 | clean: 139 | rm -rf obj_x86_64 obj_arm64 obj_universal tmp docs.json 140 | 141 | docs: 142 | hs -c "require(\"hs.doc\").builder.genJSON(\"$(dir $(mkfile_path))\")" > docs.json 143 | 144 | markdown: 145 | hs -c "dofile(\"$(MARKDOWNMAKER)\").genMarkdown([[$(dir $(mkfile_path))]])" > README.tmp.md 146 | 147 | markdownWithTOC: 148 | hs -c "dofile(\"$(MARKDOWNMAKER)\").genMarkdown([[$(dir $(mkfile_path))]], true)" > README.tmp.md 149 | 150 | release: clean all 151 | HS_APPLICATION=$(HS_APPLICATION) PREFIX=tmp make install-universal ; cd tmp ; tar -cf ../$(MODULE)-v$(VERSION).tar hs ; cd .. ; gzip $(MODULE)-v$(VERSION).tar 152 | 153 | releaseWithDocs: clean all docs 154 | HS_APPLICATION=$(HS_APPLICATION) PREFIX=tmp make install-universal ; cd tmp ; tar -cf ../$(MODULE)-v$(VERSION).tar hs ; cd .. ; gzip $(MODULE)-v$(VERSION).tar 155 | 156 | .PHONY: all clean verify install install-lua install-x86_64 install-arm64 install-universal docs markdown markdownWithTOC release releaseWithDocs 157 | -------------------------------------------------------------------------------- /bluetooth/README.md: -------------------------------------------------------------------------------- 1 | hs._asm.undocumented.bluetooth 2 | ============================== 3 | 4 | This submodule provides access to Bluetooth availability and its power state, and the ability to change it. 5 | 6 | This module utilizes undocumented or unpublished functions to manipulate options and features within OS X. These are from "private" api's for Mac OS X and are not guaranteed to work with any particular version of OS X or at all. This code was based primarily on code samples and segments found at https://github.com/toy/blueutil. 7 | 8 | I make no promises that these will work for you or work at all with any, past, current, or future versions of OS X. I can confirm only that they didn't crash my machine during testing under 10.10. You have been warned. 9 | 10 | 11 | ### Installation 12 | 13 | A precompiled version of this module can be found in this directory with a name along the lines of `bluetooth-v0.x.tar.gz`. This can be installed by downloading the file and then expanding it as follows: 14 | 15 | ~~~sh 16 | $ cd ~/.hammerspoon # or wherever your Hammerspoon init.lua file is located 17 | $ tar -xzf ~/Downloads/bluetooth-v0.x.tar.gz # or wherever your downloads are located 18 | ~~~ 19 | 20 | If you wish to build this module yourself, and have XCode installed on your Mac, the best way (you are welcome to clone the entire repository if you like, but no promises on the current state of anything else) is to download `init.lua`, `internal.m`, and `Makefile` (at present, nothing else is required) into a directory of your choice and then do the following: 21 | 22 | ~~~sh 23 | $ cd wherever-you-downloaded-the-files 24 | $ [HS_APPLICATION=/Applications] [PREFIX=~/.hammerspoon] make docs install 25 | ~~~ 26 | 27 | If your Hammerspoon application is located in `/Applications`, you can leave out the `HS_APPLICATION` environment variable, and if your Hammerspoon files are located in their default location, you can leave out the `PREFIX` environment variable. For most people it will be sufficient to just type `make docs install`. 28 | 29 | As always, whichever method you chose, if you are updating from an earlier version it is recommended to fully quit and restart Hammerspoon after installing this module to ensure that the latest version of the module is loaded into memory. 30 | 31 | ### Usage 32 | ~~~lua 33 | bluetooth = require("hs._asm.undocumented.bluetooth") 34 | ~~~ 35 | 36 | ### Contents 37 | 38 | 39 | ##### Module Functions 40 | * bluetooth.available() -> bool 41 | * bluetooth.discoverable([state]) -> bool 42 | * bluetooth.power([state]) -> bool 43 | 44 | - - - 45 | 46 | ### Module Functions 47 | 48 | 49 | ~~~lua 50 | bluetooth.available() -> bool 51 | ~~~ 52 | Returns true or false, indicating whether bluetooth is available on this machine. 53 | 54 | Parameters: 55 | * None 56 | 57 | Returns: 58 | * true if bluetooth is available on this machine, false if it is not; returns nil if bluetooth framework unavailable (this has been observed in some virtual machines) 59 | 60 | - - - 61 | 62 | 63 | ~~~lua 64 | bluetooth.discoverable([state]) -> bool 65 | ~~~ 66 | Get or set bluetooth discoverable state. 67 | 68 | Parameters: 69 | * state - an optional boolean value indicating whether bluetooth the machine should be discoverable (true) or not (false) 70 | 71 | Returns: 72 | * the (possibly changed) current value; returns nil if bluetooth framework unavailable (this has been observed in some virtual machines) 73 | 74 | Notes: 75 | * use of this method to change discoverability has been observed to cause connected devices to disconnect in rare cases; use at your own risk. 76 | 77 | - - - 78 | 79 | 80 | ~~~lua 81 | bluetooth.power([state]) -> bool 82 | ~~~ 83 | Get or set bluetooth power state. 84 | 85 | Parameters: 86 | * state - an optional boolean value indicating whether bluetooth power should be turned on (true) or off (false) 87 | 88 | Returns: 89 | * the (possibly changed) current value; returns nil if bluetooth framework unavailable (this has been observed in some virtual machines) 90 | 91 | - - - 92 | 93 | ### License 94 | 95 | > The MIT License (MIT) 96 | > 97 | > Copyright (c) 2020 Aaron Magill 98 | > 99 | > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 100 | > 101 | > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 102 | > 103 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 104 | > 105 | 106 | 107 | -------------------------------------------------------------------------------- /bluetooth/bluetooth-v0.2.1-universal.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asmagill/hammerspoon_asm.undocumented/85ab33aacdb000a609c7b6ddfa0eed415552ed59/bluetooth/bluetooth-v0.2.1-universal.tar.gz -------------------------------------------------------------------------------- /bluetooth/init.lua: -------------------------------------------------------------------------------- 1 | --- === hs._asm.undocumented.bluetooth === 2 | --- 3 | --- This submodule provides access to Bluetooth availability and its power state, and the ability to change it. 4 | --- 5 | --- This module utilizes undocumented or unpublished functions to manipulate options and features within OS X. These are from "private" api's for Mac OS X and are not guaranteed to work with any particular version of OS X or at all. This code was based primarily on code samples and segments found at https://github.com/toy/blueutil. 6 | --- 7 | ---I make no promises that these will work for you or work at all with any, past, current, or future versions of OS X. I can confirm only that they didn't crash my machine during testing under 10.10. You have been warned. 8 | 9 | local USERDATA_TAG = "hs._asm.undocumented.bluetooth" 10 | local module = require(USERDATA_TAG..".internal") 11 | 12 | local basePath = package.searchpath(USERDATA_TAG, package.path) 13 | if basePath then 14 | basePath = basePath:match("^(.+)/init.lua$") 15 | if require"hs.fs".attributes(basePath .. "/docs.json") then 16 | require"hs.doc".registerJSONFile(basePath .. "/docs.json") 17 | end 18 | end 19 | 20 | -- private variables and methods ----------------------------------------- 21 | 22 | -- Public interface ------------------------------------------------------ 23 | 24 | -- Return Module Object -------------------------------------------------- 25 | 26 | return module 27 | -------------------------------------------------------------------------------- /bluetooth/internal.m: -------------------------------------------------------------------------------- 1 | @import Cocoa ; 2 | @import LuaSkin ; 3 | @import IOBluetooth ; 4 | 5 | static LSRefTable refTable = LUA_NOREF ; 6 | 7 | // private methods 8 | extern int IOBluetoothPreferencesAvailable(void) __attribute__((weak_import)); 9 | 10 | extern int IOBluetoothPreferenceGetControllerPowerState(void) __attribute__((weak_import)); 11 | extern void IOBluetoothPreferenceSetControllerPowerState(int state) __attribute__((weak_import)); 12 | 13 | extern int IOBluetoothPreferenceGetDiscoverableState(void) __attribute__((weak_import)); 14 | extern void IOBluetoothPreferenceSetDiscoverableState(int state) __attribute__((weak_import)); 15 | 16 | #pragma clang diagnostic push 17 | #pragma clang diagnostic ignored "-Wtautological-pointer-compare" 18 | 19 | /// hs._asm.undocumented.bluetooth.available() -> bool 20 | /// Function 21 | /// Returns true or false, indicating whether bluetooth is available on this machine. 22 | /// 23 | /// Parameters: 24 | /// * None 25 | /// 26 | /// Returns: 27 | /// * true if bluetooth is available on this machine, false if it is not; returns nil if bluetooth framework unavailable (this has been observed in some virtual machines) 28 | static int bt_available(lua_State* L) { 29 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 30 | [skin checkArgs:LS_TBREAK] ; 31 | 32 | if (IOBluetoothPreferencesAvailable != NULL) { 33 | if (IOBluetoothPreferencesAvailable()) { 34 | lua_pushboolean(L, YES) ; 35 | } else { 36 | lua_pushboolean(L, NO) ; 37 | } 38 | } else { 39 | lua_pushnil(L) ; 40 | } 41 | 42 | return 1; 43 | } 44 | 45 | 46 | /// hs._asm.undocumented.bluetooth.power([state]) -> bool 47 | /// Function 48 | /// Get or set bluetooth power state. 49 | /// 50 | /// Parameters: 51 | /// * state - an optional boolean value indicating whether bluetooth power should be turned on (true) or off (false) 52 | /// 53 | /// Returns: 54 | /// * the (possibly changed) current value; returns nil if bluetooth framework unavailable (this has been observed in some virtual machines) 55 | static int bt_power(lua_State* L) { 56 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 57 | [skin checkArgs:LS_TBOOLEAN | LS_TOPTIONAL, LS_TBREAK] ; 58 | 59 | if (IOBluetoothPreferenceGetControllerPowerState != NULL && IOBluetoothPreferenceSetControllerPowerState != NULL) { 60 | if (!lua_isnone(L, 1)) { 61 | IOBluetoothPreferenceSetControllerPowerState((Boolean) lua_toboolean(L, -1)); 62 | usleep(1000000); // Apparently it doesn't like being re-queried too quickly 63 | } 64 | 65 | if (IOBluetoothPreferenceGetControllerPowerState()) { 66 | lua_pushboolean(L, YES) ; 67 | } else { 68 | lua_pushboolean(L, NO) ; 69 | } 70 | } else { 71 | lua_pushnil(L) ; 72 | } 73 | return 1; 74 | } 75 | 76 | /// hs._asm.undocumented.bluetooth.discoverable([state]) -> bool 77 | /// Function 78 | /// Get or set bluetooth discoverable state. 79 | /// 80 | /// Parameters: 81 | /// * state - an optional boolean value indicating whether bluetooth the machine should be discoverable (true) or not (false) 82 | /// 83 | /// Returns: 84 | /// * the (possibly changed) current value; returns nil if bluetooth framework unavailable (this has been observed in some virtual machines) 85 | /// 86 | /// Notes: 87 | /// * use of this method to change discoverability has been observed to cause connected devices to disconnect in rare cases; use at your own risk. 88 | /// * Opening the Bluetooth preference pane always turns on discoverability if bluetooth power is on or if it is switched on when preference pane is open; this change of discoverability is *not* reported by the API function used by this function. 89 | static int bt_discoverable(lua_State* L) { 90 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 91 | [skin checkArgs:LS_TBOOLEAN | LS_TOPTIONAL, LS_TBREAK] ; 92 | 93 | if (IOBluetoothPreferenceSetDiscoverableState != NULL && IOBluetoothPreferenceGetDiscoverableState != NULL) { 94 | if (!lua_isnone(L, 1)) { 95 | IOBluetoothPreferenceSetDiscoverableState((Boolean) lua_toboolean(L, -1)); 96 | usleep(1000000); // Apparently it doesn't like being re-queried too quickly 97 | } 98 | 99 | if (IOBluetoothPreferenceGetDiscoverableState()) { 100 | lua_pushboolean(L, YES) ; 101 | } else { 102 | lua_pushboolean(L, NO) ; 103 | } 104 | } else { 105 | lua_pushnil(L) ; 106 | } 107 | return 1; 108 | } 109 | 110 | #pragma clang diagnostic pop 111 | 112 | static const luaL_Reg moduleLib[] = { 113 | {"available", bt_available}, 114 | {"power", bt_power}, 115 | {"discoverable", bt_discoverable}, 116 | {NULL, NULL} 117 | }; 118 | 119 | int luaopen_hs__asm_undocumented_bluetooth_internal(lua_State* L) { 120 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 121 | refTable = [skin registerLibrary:"hs._asm.undocumented.bluetooth" functions:moduleLib metaFunctions:nil] ; 122 | 123 | return 1; 124 | } 125 | -------------------------------------------------------------------------------- /cgsdebug/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Aaron Magill 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /cgsdebug/Makefile: -------------------------------------------------------------------------------- 1 | mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) 2 | current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) 3 | 4 | MODULE := $(current_dir) 5 | PREFIX ?= ~/.hammerspoon 6 | HS_APPLICATION ?= /Applications 7 | 8 | OBJCFILE = ${wildcard *.m} 9 | LUAFILE = ${wildcard *.lua} 10 | HEADERS = ${wildcard *.h} 11 | 12 | SOFILE := $(OBJCFILE:.m=.so) 13 | DEBUG_CFLAGS ?= -g 14 | DOC_FILE = hs._asm.undocumented.$(MODULE).json 15 | 16 | # special vars for uninstall 17 | space := 18 | space += 19 | comma := , 20 | ALLFILES := $(LUAFILE) 21 | ALLFILES += $(SOFILE) 22 | 23 | .SUFFIXES: .m .so 24 | 25 | #CC=cc 26 | CC=clang 27 | EXTRA_CFLAGS ?= -Wconversion -Wdeprecated -F$(HS_APPLICATION)/Hammerspoon.app/Contents/Frameworks 28 | CFLAGS += $(DEBUG_CFLAGS) -fobjc-arc -DHS_EXTERNAL_MODULE -Wall -Wextra $(EXTRA_CFLAGS) 29 | LDFLAGS += -dynamiclib -undefined dynamic_lookup $(EXTRA_LDFLAGS) 30 | 31 | DOC_SOURCES = $(LUAFILE) $(OBJCFILE) 32 | 33 | all: verify $(SOFILE) 34 | 35 | .m.so: $(HEADERS) 36 | $(CC) $< $(CFLAGS) $(LDFLAGS) -o $@ 37 | 38 | install: verify install-objc install-lua 39 | 40 | verify: $(LUAFILE) 41 | luac -p $(LUAFILE) && echo "Passed" 42 | 43 | install-objc: $(SOFILE) 44 | mkdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE) 45 | install -m 0644 $(SOFILE) $(PREFIX)/hs/_asm/undocumented/$(MODULE) 46 | cp -vpR $(OBJCFILE:.m=.so.dSYM) $(PREFIX)/hs/_asm/undocumented/$(MODULE) 47 | 48 | install-lua: $(LUAFILE) 49 | mkdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE) 50 | install -m 0644 $(LUAFILE) $(PREFIX)/hs/_asm/undocumented/$(MODULE) 51 | 52 | docs: $(DOC_FILE) 53 | 54 | $(DOC_FILE): $(DOC_SOURCES) 55 | find . -type f \( -name '*.lua' -o -name '*.m' \) -not -name 'template.*' -not -path './_*' -exec cat {} + | __doc_tools/gencomments | __doc_tools/genjson > $@ 56 | 57 | install-docs: docs 58 | mkdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE) 59 | install -m 0644 $(DOC_FILE) $(PREFIX)/hs/_asm/undocumented/$(MODULE) 60 | 61 | clean: 62 | rm -v -rf $(SOFILE) *.dSYM $(DOC_FILE) 63 | 64 | uninstall: 65 | rm -v -f $(PREFIX)/hs/_asm/undocumented/$(MODULE)/{$(subst $(space),$(comma),$(ALLFILES))} 66 | (pushd $(PREFIX)/hs/_asm/undocumented/$(MODULE)/ ; rm -v -fr $(OBJCFILE:.m=.so.dSYM) ; popd) 67 | rm -v -f $(PREFIX)/hs/_asm/undocumented/$(MODULE)/$(DOC_FILE) 68 | rmdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE) ; exit 0 69 | 70 | .PHONY: all clean uninstall verify docs install install-objc install-lua install-docs 71 | -------------------------------------------------------------------------------- /cgsdebug/README.md: -------------------------------------------------------------------------------- 1 | _asm.undocumented.cgsdebug 2 | ========================== 3 | 4 | ***NOTE: This module does not work under OS X 10.11 due to security restrictions added to limit which applications can make change requests to the window server. I am looking for a work around, but it doesn't look promising. Please file an issue if you are aware of a work around or have any ideas.*** 5 | 6 | Functions to get and set undocumented options and features within OS X. These are undocumented features from the "private" api's for Mac OS X and are not guaranteed to work with any particular version of OS X or at all. This code was based primarily on code samples and segments found at (https://code.google.com/p/undocumented-goodness/) and (https://code.google.com/p/iterm2/source/browse/branches/0.10.x/CGSInternal/CGSDebug.h?r=2). 7 | 8 | This submodule provides access to CGSDebug related features. Most notably, this contains the hydra.shadow(bool) functionality, and a specific function is provided for just that functionality. 9 | 10 | I make no promises that these will work for you or work at all with any, past, current, or future versions of OS X. I can confirm only that they didn't crash my machine during testing under 10.10. You have been warned. 11 | 12 | ### Installation 13 | 14 | This does require that you have XCode or the XCode Command Line Tools installed. See the App Store application or https://developer.apple.com to install these if necessary. 15 | 16 | ~~~bash 17 | $ git clone https://github.com/asmagill/hammerspoon_asm.undocumented undocumented 18 | $ cd undocumented/cgsdebug 19 | $ [HS_APPLICATION=/Applications] [PREFIX=~/.hammerspoon] make install 20 | ~~~ 21 | 22 | If Hammerspoon.app is in your /Applications folder, you may leave `HS_APPLICATION=/Applications` out and if you are fine with the module being installed in your Hammerspoon configuration directory, you may leave `PREFIX=~/.hammerspoon` out as well. For most people, it will probably be sufficient to just type `make install`. 23 | 24 | ### Require 25 | 26 | ~~~lua 27 | cgsdebug = require("hs._asm.undocumented.cgsdebug") 28 | ~~~ 29 | 30 | ### Functions 31 | 32 | ~~~lua 33 | cgsdebug.get(option) -> boolean 34 | ~~~ 35 | Returns a boolean indicating whether the specified CGSDebug option is set or not where `option` is a number corresponding to a label defined in `cgsdebug.options[]`. 36 | 37 | ~~~lua 38 | cgsdebug.set(option, boolean) 39 | ~~~ 40 | Enables (value == true) or disables (value == false) the specified CGSDebug option where `option` is a number corresponding to a label defined in `cgsdebug.options[]`. 41 | 42 | ~~~lua 43 | cgsdebug.clear() 44 | ~~~ 45 | Clears all of the CGSDebug option flags. 46 | 47 | ~~~lua 48 | cgsdebug.getMask() -> number 49 | ~~~ 50 | Returns the numeric value representing the bitmask of all currently set CGSDebug options. 51 | 52 | ~~~lua 53 | cgsdebug.shadow(bool) 54 | ~~~ 55 | Sets whether OSX apps have shadows. 56 | 57 | ### Variables 58 | 59 | ~~~lua 60 | cgsdebug.options[] 61 | ~~~ 62 | Convenience table of the currently known debug options. 63 | 64 | | Option | Description | 65 | |:-------------------------|-------------| 66 | | flashScreenUpdates | All screen updates are flashed in yellow. Regions under a DisableUpdate are flashed in orange. Regions that are hardware accellerated are painted green. | 67 | | colorByAccelleration | Colors windows green if they are accellerated, otherwise red. Doesn't cause things to refresh properly - leaves excess rects cluttering the screen. | 68 | | noShadows | Disables shadows on all windows. | 69 | | noDelayAfterFlash | Setting this disables the pause after a flash when using FlashScreenUpdates or FlashIdenticalUpdates. | 70 | | autoflushDrawing | Flushes the contents to the screen after every drawing operation. | 71 | | showMouseTrackingAreas | Highlights mouse tracking areas. Doesn't cause things to refresh correctly - leaves excess rectangles cluttering the screen. | 72 | | flashIdenticalUpdates | Flashes identical updates in red. | 73 | | dumpWindowListToFile | Dumps a list of windows to /tmp/WindowServer.winfo.out. This is what Quartz Debug uses to get the window list. | 74 | | dumpConnectionListToFile | Dumps a list of connections to /tmp/WindowServer.cinfo.out. | 75 | | verboseLogging | Dumps a very verbose debug log of the WindowServer to /tmp/CGLog_WinServer_. | 76 | | verboseLoggingAllApps | Dumps a very verbose debug log of all processes to /tmp/CGLog__. | 77 | | dumpHotKeyListToFile | Dumps a list of hotkeys to /tmp/WindowServer.keyinfo.out. | 78 | | dumpSurfaceInfo | Dumps SurfaceInfo? to /tmp/WindowServer.sinfo.out | 79 | | dumpOpenGLInfoToFile | Dumps information about OpenGL extensions, etc to /tmp/WindowServer.glinfo.out. | 80 | | dumpShadowListToFile | Dumps a list of shadows to /tmp/WindowServer.shinfo.out. | 81 | | dumpWindowListToPlist | Dumps a list of windows to `/tmp/WindowServer.winfo.plist`. This is what Quartz Debug on 10.5 uses to get the window list. | 82 | | dumpResourceUsageToFiles | Dumps information about an application's resource usage to `/tmp/CGResources__`. | 83 | 84 | ### License 85 | 86 | > Released under MIT license. 87 | > 88 | > Copyright (c) 2015 Aaron Magill 89 | > 90 | > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 91 | > 92 | > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 93 | > 94 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 95 | -------------------------------------------------------------------------------- /cgsdebug/cgsdebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Routines for debugging the window server and application drawing. 3 | * 4 | * Copyright (C) 2007-2008 Alacatia Labs 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 2. Altered source versions must be plainly marked as such, and must not be 19 | * misrepresented as being the original software. 20 | * 3. This notice may not be removed or altered from any source distribution. 21 | * 22 | * Joe Ranieri joe@alacatia.com 23 | * 24 | */ 25 | 26 | typedef enum { 27 | /*! Clears all flags. */ 28 | kCGSDebugOptionNone = 0, 29 | 30 | /*! All screen updates are flashed in yellow. Regions under a DisableUpdate are flashed in orange. Regions that are hardware accellerated are painted green. */ 31 | kCGSDebugOptionFlashScreenUpdates = 0x4, 32 | 33 | /*! Colors windows green if they are accellerated, otherwise red. Doesn't cause things to refresh properly - leaves excess rects cluttering the screen. */ 34 | kCGSDebugOptionColorByAccelleration = 0x20, 35 | 36 | /*! Disables shadows on all windows. */ 37 | kCGSDebugOptionNoShadows = 0x4000, 38 | 39 | /*! Setting this disables the pause after a flash when using FlashScreenUpdates or FlashIdenticalUpdates. */ 40 | kCGSDebugOptionNoDelayAfterFlash = 0x20000, 41 | 42 | /*! Flushes the contents to the screen after every drawing operation. */ 43 | kCGSDebugOptionAutoflushDrawing = 0x40000, 44 | 45 | /*! Highlights mouse tracking areas. Doesn't cause things to refresh correctly - leaves excess rectangles cluttering the screen. */ 46 | kCGSDebugOptionShowMouseTrackingAreas = 0x100000, 47 | 48 | /*! Flashes identical updates in red. */ 49 | kCGSDebugOptionFlashIdenticalUpdates = 0x4000000, 50 | 51 | /*! Dumps a list of windows to /tmp/WindowServer.winfo.out. This is what Quartz Debug uses to get the window list. */ 52 | kCGSDebugOptionDumpWindowListToFile = 0x80000001, 53 | 54 | /*! Dumps a list of connections to /tmp/WindowServer.cinfo.out. */ 55 | kCGSDebugOptionDumpConnectionListToFile = 0x80000002, 56 | 57 | /*! Dumps a very verbose debug log of the WindowServer to /tmp/CGLog_WinServer_. */ 58 | kCGSDebugOptionVerboseLogging = 0x80000006, 59 | 60 | /*! Dumps a very verbose debug log of all processes to /tmp/CGLog__. */ 61 | kCGSDebugOptionVerboseLoggingAllApps = 0x80000007, 62 | 63 | /*! Dumps a list of hotkeys to /tmp/WindowServer.keyinfo.out. */ 64 | kCGSDebugOptionDumpHotKeyListToFile = 0x8000000E, 65 | 66 | /*! Dumps SurfaceInfo? to /tmp/WindowServer.sinfo.out */ 67 | kCGSDebugOptionDumpSurfaceInfo = 0x80000010, 68 | 69 | /*! Dumps information about OpenGL extensions, etc to /tmp/WindowServer.glinfo.out. */ 70 | kCGSDebugOptionDumpOpenGLInfoToFile = 0x80000013, 71 | 72 | /*! Dumps a list of shadows to /tmp/WindowServer.shinfo.out. */ 73 | kCGSDebugOptionDumpShadowListToFile = 0x80000014, 74 | 75 | /*! Leopard: Dumps a list of windows to `/tmp/WindowServer.winfo.plist`. This is what Quartz Debug on 10.5 uses to get the window list. */ 76 | kCGSDebugOptionDumpWindowListToPlist = 0x80000017, 77 | 78 | /*! Leopard: Dumps information about an application's resource usage to `/tmp/CGResources__`. */ 79 | kCGSDebugOptionDumpResourceUsageToFiles = 0x80000020, 80 | } CGSDebugOption; 81 | 82 | 83 | /*! Gets and sets the debug options. These options are global and are not reset when your application dies! */ 84 | extern CGError CGSGetDebugOptions(CGSDebugOption *outCurrentOptions); 85 | extern CGError CGSSetDebugOptions(CGSDebugOption options); 86 | -------------------------------------------------------------------------------- /cgsdebug/init.lua: -------------------------------------------------------------------------------- 1 | --- === hs._asm.undocumented.cgsdebug === 2 | --- 3 | --- This submodule provides access to CGSDebug related features. Most notably, this contains the original `hydra.shadow(bool)` functionality, and a specific function is provided for just that functionality. 4 | --- 5 | --- This module utilizes undocumented or unpublished functions to manipulate options and features within OS X. These are from "private" api's for Mac OS X and are not guaranteed to work with any particular version of OS X or at all.This code was based primarily on code samples and segments found at (https://code.google.com/p/undocumented-goodness/) and (https://code.google.com/p/iterm2/source/browse/branches/0.10.x/CGSInternal/CGSDebug.h?r=2). 6 | --- 7 | --- 8 | --- I make no promises that these will work for you or work at all with any, past, current, or future versions of OS X. I can confirm only that they didn't crash my machine during testing under 10.10. You have been warned. 9 | 10 | 11 | local module = require("hs._asm.undocumented.cgsdebug.internal") 12 | 13 | -- private variables and methods ----------------------------------------- 14 | 15 | local _kMetaTable = {} 16 | _kMetaTable._k = {} 17 | _kMetaTable.__index = function(obj, key) 18 | if _kMetaTable._k[obj] then 19 | if _kMetaTable._k[obj][key] then 20 | return _kMetaTable._k[obj][key] 21 | else 22 | for k,v in pairs(_kMetaTable._k[obj]) do 23 | if v == key then return k end 24 | end 25 | end 26 | end 27 | return nil 28 | end 29 | _kMetaTable.__newindex = function(obj, key, value) 30 | error("attempt to modify a table of constants",2) 31 | return nil 32 | end 33 | _kMetaTable.__pairs = function(obj) return pairs(_kMetaTable._k[obj]) end 34 | _kMetaTable.__tostring = function(obj) 35 | local result = "" 36 | if _kMetaTable._k[obj] then 37 | local width = 0 38 | for k,v in pairs(_kMetaTable._k[obj]) do width = width < #k and #k or width end 39 | for k,v in require("hs.fnutils").sortByKeys(_kMetaTable._k[obj]) do 40 | result = result..string.format("%-"..tostring(width).."s %s\n", k, tostring(v)) 41 | end 42 | else 43 | result = "constants table missing" 44 | end 45 | return result 46 | end 47 | _kMetaTable.__metatable = _kMetaTable -- go ahead and look, but don't unset this 48 | 49 | local _makeConstantsTable = function(theTable) 50 | local results = setmetatable({}, _kMetaTable) 51 | _kMetaTable._k[results] = theTable 52 | return results 53 | end 54 | 55 | -- Public interface ------------------------------------------------------ 56 | 57 | module.options = _makeConstantsTable(module.options) 58 | 59 | -- Return Module Object -------------------------------------------------- 60 | 61 | return module 62 | 63 | -------------------------------------------------------------------------------- /cgsdebug/internal.m: -------------------------------------------------------------------------------- 1 | #import 2 | // #import 3 | #import 4 | #import "cgsdebug.h" 5 | 6 | int refTable ; 7 | 8 | /// hs._asm.undocumented.cgsdebug.cgsdebug.get(option) -> boolean 9 | /// Function 10 | /// Returns the current state of the CGSDebug option specified by `option` 11 | /// 12 | /// Parameters: 13 | /// * option - a number corresponding to a label defined in `hs._asm.undocumented.cgsdebug.cgsdebug.options[]`. 14 | /// 15 | /// Returns: 16 | /// * the current state as a boolean 17 | static int cgsdebug_get(lua_State* L) { 18 | [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ; 19 | 20 | CGSDebugOption the_option = (CGSDebugOption)luaL_checkinteger(L, 1); 21 | CGSDebugOption actual_options; 22 | CGSGetDebugOptions(&actual_options) ; 23 | 24 | if (actual_options & the_option) 25 | lua_pushboolean(L, YES); 26 | else 27 | lua_pushboolean(L, NO); 28 | return 1; 29 | } 30 | 31 | /// hs._asm.undocumented.cgsdebug.cgsdebug.set(option, value) -> none 32 | /// Function 33 | /// Enable or disable the CGSDebug option specified 34 | /// 35 | /// Parameters: 36 | /// * option - a number corresponding to a label defined in `hs._asm.undocumented.cgsdebug.cgsdebug.options[]`. 37 | /// * value - a boolean value indicating whether the option should be enabled (true) or disabled (false) 38 | /// 39 | /// Returns: 40 | /// * None 41 | static int cgsdebug_set(lua_State* L) { 42 | [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBOOLEAN, LS_TBREAK] ; 43 | 44 | CGSDebugOption the_option = (CGSDebugOption)luaL_checkinteger(L, 1); 45 | BOOL on = (BOOL)lua_toboolean(L, 2); 46 | 47 | CGSDebugOption actual_options; 48 | CGSGetDebugOptions(&actual_options) ; 49 | actual_options = on ? (actual_options | the_option) : (actual_options & ~the_option); 50 | CGSSetDebugOptions(actual_options); 51 | return 0; 52 | } 53 | 54 | /// hs._asm.undocumented.cgsdebug.cgsdebug.clear() -> none 55 | /// Function 56 | /// Clears (disables) all of the CGSDebug option flags. 57 | /// 58 | /// Parameters: 59 | /// * None 60 | /// 61 | /// Returns: 62 | /// * None 63 | static int cgsdebug_clear(lua_State* __unused L) { 64 | [[LuaSkin shared] checkArgs:LS_TBREAK] ; 65 | 66 | CGSSetDebugOptions(kCGSDebugOptionNone); 67 | return 0; 68 | } 69 | 70 | /// hs._asm.undocumented.cgsdebug.cgsdebug.getMask() -> bitmask 71 | /// Function 72 | /// Returns the integer value representing the bitmask of all currently enabled CGSDebug options. 73 | /// 74 | /// Parameters: 75 | /// * None 76 | /// 77 | /// Returns: 78 | /// * the integer value representing the bitmask of all currently enabled CGSDebug options 79 | static int cgsdebug_mask(lua_State* L) { 80 | [[LuaSkin shared] checkArgs:LS_TBREAK] ; 81 | 82 | CGSDebugOption options; 83 | CGSGetDebugOptions(&options) ; 84 | 85 | lua_pushinteger(L, options) ; 86 | return 1; 87 | } 88 | 89 | /// hs._asm.undocumented.cgsdebug.cgsdebug.shadow(state) -> none 90 | /// Function 91 | /// Enable or disable whether or not OSX Applications have shadows. 92 | /// 93 | /// Parameters: 94 | /// * state - a boolean value indicating whether or not OS X windows should have shadows 95 | /// 96 | /// Returns: 97 | /// * None 98 | static int cgsdebug_shadow(lua_State* L) { 99 | [[LuaSkin shared] checkArgs:LS_TBOOLEAN, LS_TBREAK] ; 100 | 101 | BOOL on = (BOOL)lua_toboolean(L, 1); 102 | 103 | CGSDebugOption options; 104 | CGSGetDebugOptions(&options); 105 | options = on ? (options & ~(unsigned int)kCGSDebugOptionNoShadows) : (options | kCGSDebugOptionNoShadows); 106 | CGSSetDebugOptions(options); 107 | return 0; 108 | } 109 | 110 | /// hs._asm.undocumented.cgsdebug.cgsdebug.options[] 111 | /// Variable 112 | /// Connivence array of all currently known debug options. 113 | /// 114 | /// * flashScreenUpdates - All screen updates are flashed in yellow. Regions under a DisableUpdate are flashed in orange. Regions that are hardware accellerated are painted green. 115 | /// * colorByAcceleration - Colors windows green if they are accellerated, otherwise red. Doesn't cause things to refresh properly - leaves excess rects cluttering the screen. 116 | /// * noShadows - Disables shadows on all windows. 117 | /// * noDelayAfterFlash - Setting this disables the pause after a flash when using FlashScreenUpdates or FlashIdenticalUpdates. 118 | /// * autoflushDrawing - Flushes the contents to the screen after every drawing operation. 119 | /// * showMouseTrackingAreas - Highlights mouse tracking areas. Doesn't cause things to refresh correctly - leaves excess rectangles cluttering the screen. 120 | /// * flashIdenticalUpdates - Flashes identical updates in red. 121 | /// * dumpWindowListToFile - Dumps a list of windows to /tmp/WindowServer.winfo.out. This is what Quartz Debug uses to get the window list. 122 | /// * dumpConnectionListToFile - Dumps a list of connections to /tmp/WindowServer.cinfo.out. 123 | /// * verboseLogging - Dumps a very verbose debug log of the WindowServer to /tmp/CGLog_WinServer_PID. 124 | /// * verboseLoggingAllApps - Dumps a very verbose debug log of all processes to /tmp/CGLog_NAME_PID. 125 | /// * dumpHotKeyListToFile - Dumps a list of hotkeys to /tmp/WindowServer.keyinfo.out. 126 | /// * dumpSurfaceInfo - Dumps SurfaceInfo? to /tmp/WindowServer.sinfo.out 127 | /// * dumpOpenGLInfoToFile - Dumps information about OpenGL extensions, etc to /tmp/WindowServer.glinfo.out. 128 | /// * dumpShadowListToFile - Dumps a list of shadows to /tmp/WindowServer.shinfo.out. 129 | /// * dumpWindowListToPlist - Dumps a list of windows to `/tmp/WindowServer.winfo.plist`. This is what Quartz Debug on 10.5 uses to get the window list. 130 | /// * dumpResourceUsageToFiles - Dumps information about an application's resource usage to `/tmp/CGResources_NAME_PID`. 131 | static void cgsdebug_options (lua_State *L) { 132 | lua_newtable(L) ; 133 | // lua_pushinteger(L, kCGSDebugOptionNone); lua_setfield(L, -2, "none") ; 134 | lua_pushinteger(L, kCGSDebugOptionFlashScreenUpdates); lua_setfield(L, -2, "flashScreenUpdates") ; 135 | lua_pushinteger(L, kCGSDebugOptionColorByAccelleration); lua_setfield(L, -2, "colorByAcceleration") ; 136 | lua_pushinteger(L, kCGSDebugOptionNoShadows); lua_setfield(L, -2, "noShadows") ; 137 | lua_pushinteger(L, kCGSDebugOptionNoDelayAfterFlash); lua_setfield(L, -2, "noDelayAfterFlash") ; 138 | lua_pushinteger(L, kCGSDebugOptionAutoflushDrawing); lua_setfield(L, -2, "autoFlushDrawing") ; 139 | lua_pushinteger(L, kCGSDebugOptionShowMouseTrackingAreas); lua_setfield(L, -2, "showMouseTrackingAreas") ; 140 | lua_pushinteger(L, kCGSDebugOptionFlashIdenticalUpdates); lua_setfield(L, -2, "flashIdenticalUpdates") ; 141 | lua_pushinteger(L, kCGSDebugOptionDumpWindowListToFile); lua_setfield(L, -2, "dumpWindowListToFile") ; 142 | lua_pushinteger(L, kCGSDebugOptionDumpConnectionListToFile); lua_setfield(L, -2, "dumpConnectionListToFile") ; 143 | lua_pushinteger(L, kCGSDebugOptionVerboseLogging); lua_setfield(L, -2, "verboseLogging") ; 144 | lua_pushinteger(L, kCGSDebugOptionVerboseLoggingAllApps); lua_setfield(L, -2, "verboseLoggingAllApps") ; 145 | lua_pushinteger(L, kCGSDebugOptionDumpHotKeyListToFile); lua_setfield(L, -2, "dumpHotKeyListToFile") ; 146 | lua_pushinteger(L, kCGSDebugOptionDumpSurfaceInfo); lua_setfield(L, -2, "dumpSurfaceInfo") ; 147 | lua_pushinteger(L, kCGSDebugOptionDumpOpenGLInfoToFile); lua_setfield(L, -2, "dumpOpenGLInfoToFile") ; 148 | lua_pushinteger(L, kCGSDebugOptionDumpShadowListToFile); lua_setfield(L, -2, "dumpShadowListToFile") ; 149 | lua_pushinteger(L, kCGSDebugOptionDumpWindowListToPlist); lua_setfield(L, -2, "dumpWindowListToPlist") ; 150 | lua_pushinteger(L, kCGSDebugOptionDumpResourceUsageToFiles); lua_setfield(L, -2, "dumpResourceUsageToFiles") ; 151 | } 152 | 153 | static const luaL_Reg moduleLib[] = { 154 | {"get", cgsdebug_get}, 155 | {"set", cgsdebug_set}, 156 | {"clear", cgsdebug_clear}, 157 | {"getMask", cgsdebug_mask}, 158 | {"shadow", cgsdebug_shadow}, 159 | {NULL, NULL} 160 | }; 161 | 162 | int luaopen_hs__asm_undocumented_cgsdebug_internal(lua_State* L) { 163 | refTable = [[LuaSkin shared] registerLibrary:moduleLib metaFunctions:nil] ; 164 | 165 | cgsdebug_options(L) ; lua_setfield(L, -2, "options") ; 166 | return 1; 167 | } 168 | -------------------------------------------------------------------------------- /coredock/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Aaron Magill 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /coredock/Makefile: -------------------------------------------------------------------------------- 1 | mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) 2 | current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) 3 | 4 | MODULE := $(lastword $(subst ., ,$(current_dir))) 5 | PREFIX ?= ~/.hammerspoon 6 | MODPATH = hs/_asm/undocumented 7 | VERSION ?= 0.x 8 | HS_APPLICATION ?= /Applications 9 | 10 | # get from https://github.com/asmagill/hammerspoon-config/blob/master/utils/docmaker.lua 11 | # if you want to generate a readme file similar to the ones I generally use. Adjust the copyright in the file and adjust 12 | # this variable to match where you save docmaker.lua relative to your hammerspoon configuration directory 13 | # (usually ~/.hammerspoon) 14 | MARKDOWNMAKER = utils/docmaker.lua 15 | 16 | OBJCFILES = ${wildcard *.m} 17 | LUAFILES = ${wildcard *.lua} 18 | HEADERS = ${wildcard *.h} 19 | 20 | # for compiling each source file into a separate library 21 | # (see also obj_x86_64/%.s and obj_arm64/%.s below) 22 | SOFILES := $(OBJCFILES:.m=.so) 23 | 24 | # for compiling all source files into one library 25 | # (see also obj_x86_64/%.s and obj_arm64/%.s below) 26 | # SOFILES := internal.so 27 | 28 | SOFILES_x86_64 := $(addprefix obj_x86_64/,$(SOFILES)) 29 | SOFILES_arm64 := $(addprefix obj_arm64/,$(SOFILES)) 30 | SOFILES_univeral := $(addprefix obj_universal/,$(SOFILES)) 31 | 32 | DEBUG_CFLAGS ?= -g 33 | 34 | # special vars for uninstall 35 | space := 36 | space += 37 | comma := , 38 | ALLFILES := $(LUAFILES) 39 | ALLFILES += $(SOFILES) 40 | 41 | # CC=clang 42 | CC=@clang 43 | WARNINGS ?= -Weverything -Wno-objc-missing-property-synthesis -Wno-implicit-atomic-properties -Wno-direct-ivar-access -Wno-cstring-format-directive -Wno-padded -Wno-covered-switch-default -Wno-missing-prototypes -Werror-implicit-function-declaration -Wno-documentation-unknown-command -Wno-poison-system-directories 44 | EXTRA_CFLAGS ?= -F$(HS_APPLICATION)/Hammerspoon.app/Contents/Frameworks -mmacosx-version-min=10.13 45 | 46 | CFLAGS += $(DEBUG_CFLAGS) -fmodules -fobjc-arc -DHS_EXTERNAL_MODULE $(WARNINGS) $(EXTRA_CFLAGS) 47 | LDFLAGS += -dynamiclib -undefined dynamic_lookup $(EXTRA_LDFLAGS) 48 | 49 | all: verify $(shell uname -m) 50 | 51 | x86_64: $(SOFILES_x86_64) 52 | 53 | arm64: $(SOFILES_arm64) 54 | 55 | universal: verify x86_64 arm64 $(SOFILES_univeral) 56 | 57 | # for compiling each source file into a separate library 58 | # (see also SOFILES above) 59 | 60 | obj_x86_64/%.so: %.m $(HEADERS) 61 | $(CC) $< $(CFLAGS) $(LDFLAGS) -target x86_64-apple-macos10.13 -o $@ 62 | 63 | obj_arm64/%.so: %.m $(HEADERS) 64 | $(CC) $< $(CFLAGS) $(LDFLAGS) -target arm64-apple-macos11 -o $@ 65 | 66 | # for compiling all source files into one library 67 | # (see also SOFILES above) 68 | 69 | # obj_x86_64/%.so: $(OBJCFILES) $(HEADERS) 70 | # $(CC) $(OBJCFILES) $(CFLAGS) $(LDFLAGS) -target x86_64-apple-macos10.13 -o $@ 71 | # 72 | # obj_arm64/%.so: $(OBJCFILES) $(HEADERS) 73 | # $(CC) $(OBJCFILES) $(CFLAGS) $(LDFLAGS) -target arm64-apple-macos11 -o $@ 74 | 75 | # creating the universal dSYM bundle is a total hack because I haven't found a better 76 | # way yet... suggestions welcome 77 | obj_universal/%.so: $(SOFILES_x86_64) $(SOFILES_arm64) 78 | lipo -create -output $@ $(subst universal/,x86_64/,$@) $(subst universal/,arm64/,$@) 79 | mkdir -p $@.dSYM/Contents/Resources/DWARF/ 80 | cp $(subst universal/,x86_64/,$@).dSYM/Contents/Info.plist $@.dSYM/Contents 81 | lipo -create -output $@.dSYM/Contents/Resources/DWARF/$(subst obj_universal/,,$@) $(subst universal/,x86_64/,$@).dSYM/Contents/Resources/DWARF/$(subst obj_universal/,,$@) $(subst universal/,arm64/,$@).dSYM/Contents/Resources/DWARF/$(subst obj_universal/,,$@) 82 | 83 | $(SOFILES_x86_64): | obj_x86_64 84 | 85 | $(SOFILES_arm64): | obj_arm64 86 | 87 | $(SOFILES_univeral): | obj_universal 88 | 89 | obj_x86_64: 90 | mkdir obj_x86_64 91 | 92 | obj_arm64: 93 | mkdir obj_arm64 94 | 95 | obj_universal: 96 | mkdir obj_universal 97 | 98 | verify: $(LUAFILES) 99 | @if $$(hash lua >& /dev/null); then (luac -p $(LUAFILES) && echo "Lua Compile Verification Passed"); else echo "Skipping Lua Compile Verification"; fi 100 | 101 | install: install-$(shell uname -m) 102 | 103 | install-lua: $(LUAFILES) 104 | mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE) 105 | install -m 0644 $(LUAFILES) $(PREFIX)/$(MODPATH)/$(MODULE) 106 | test -f docs.json && install -m 0644 docs.json $(PREFIX)/$(MODPATH)/$(MODULE) || echo "No docs.json file to install" 107 | 108 | install-x86_64: verify install-lua $(SOFILES_x86_64) 109 | mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE) 110 | install -m 0644 $(SOFILES_x86_64) $(PREFIX)/$(MODPATH)/$(MODULE) 111 | cp -vpR $(SOFILES_x86_64:.so=.so.dSYM) $(PREFIX)/$(MODPATH)/$(MODULE) 112 | 113 | install-arm64: verify install-lua $(SOFILES_arm64) 114 | mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE) 115 | install -m 0644 $(SOFILES_arm64) $(PREFIX)/$(MODPATH)/$(MODULE) 116 | cp -vpR $(SOFILES_arm64:.so=.so.dSYM) $(PREFIX)/$(MODPATH)/$(MODULE) 117 | 118 | install-universal: verify install-lua $(SOFILES_univeral) 119 | mkdir -p $(PREFIX)/$(MODPATH)/$(MODULE) 120 | install -m 0644 $(SOFILES_univeral) $(PREFIX)/$(MODPATH)/$(MODULE) 121 | cp -vpR $(SOFILES_univeral:.so=.so.dSYM) $(PREFIX)/$(MODPATH)/$(MODULE) 122 | 123 | uninstall: 124 | rm -v -f $(PREFIX)/$(MODPATH)/$(MODULE)/{$(subst $(space),$(comma),$(ALLFILES))} 125 | (pushd $(PREFIX)/$(MODPATH)/$(MODULE)/ ; rm -v -fr $(SOFILES:.so=.so.dSYM) ; popd) 126 | rm -v -f $(PREFIX)/$(MODPATH)/$(MODULE)/docs.json 127 | rmdir -p $(PREFIX)/$(MODPATH)/$(MODULE) ; exit 0 128 | 129 | clean: 130 | rm -rf obj_x86_64 obj_arm64 obj_universal tmp docs.json 131 | 132 | docs: 133 | hs -c "require(\"hs.doc\").builder.genJSON(\"$(dir $(mkfile_path))\")" > docs.json 134 | 135 | markdown: 136 | hs -c "dofile(\"$(MARKDOWNMAKER)\").genMarkdown([[$(dir $(mkfile_path))]])" > README.tmp.md 137 | 138 | markdownWithTOC: 139 | hs -c "dofile(\"$(MARKDOWNMAKER)\").genMarkdown([[$(dir $(mkfile_path))]], true)" > README.tmp.md 140 | 141 | release: clean all 142 | HS_APPLICATION=$(HS_APPLICATION) PREFIX=tmp make install-universal ; cd tmp ; tar -cf ../$(MODULE)-v$(VERSION).tar hs ; cd .. ; gzip $(MODULE)-v$(VERSION).tar 143 | 144 | releaseWithDocs: clean all docs 145 | HS_APPLICATION=$(HS_APPLICATION) PREFIX=tmp make install-universal ; cd tmp ; tar -cf ../$(MODULE)-v$(VERSION).tar hs ; cd .. ; gzip $(MODULE)-v$(VERSION).tar 146 | 147 | .PHONY: all clean verify install install-lua install-x86_64 install-arm64 install-universal docs markdown markdownWithTOC release releaseWithDocs 148 | -------------------------------------------------------------------------------- /coredock/README.md: -------------------------------------------------------------------------------- 1 | _asm.undocumented.coredock 2 | ========================== 3 | 4 | Functions to get and set undocumented options and features within OS X. These are undocumented features from the "private" api's for Mac OS X and are not guaranteed to work with any particular version of OS X or at all. This code was based primarily on code samples and segments found at (https://code.google.com/p/undocumented-goodness/) and (https://code.google.com/p/iterm2/source/browse/branches/0.10.x/CGSInternal/CGSDebug.h?r=2). 5 | 6 | This submodule provides access to CoreDock related features. This allows you to adjust the Dock's position, pinning, hiding, magnification and animation settings. 7 | 8 | I make no promises that these will work for you or work at all with any, past, current, or future versions of OS X. I can confirm only that they didn't crash my machine during testing under 10.10. You have been warned. 9 | 10 | Note that the top orientation and dock pinning has not been supported even within the private APIs for some time and may disappear from here in a future release unless another solution can be found. It is provided here for testing and to encourage suggestions if someone is aware of a solution that has not yet been tried. 11 | 12 | ### Installation 13 | 14 | This does require that you have XCode or the XCode Command Line Tools installed. See the App Store application or https://developer.apple.com to install these if necessary. 15 | 16 | ~~~bash 17 | $ git clone https://github.com/asmagill/hammerspoon_asm.undocumented undocumented 18 | $ cd undocumented/coredock 19 | $ [HS_APPLICATION=/Applications] [PREFIX=~/.hammerspoon] make install 20 | ~~~ 21 | 22 | If Hammerspoon.app is in your /Applications folder, you may leave `HS_APPLICATION=/Applications` out and if you are fine with the module being installed in your Hammerspoon configuration directory, you may leave `PREFIX=~/.hammerspoon` out as well. For most people, it will probably be sufficient to just type `make install`. 23 | 24 | ### Require 25 | 26 | ~~~lua 27 | coredock = require("hs._asm.undocumented.coredock") 28 | ~~~ 29 | 30 | ### Functions 31 | 32 | ~~~lua 33 | coredock.animationEffect([effect]) -> effect 34 | ~~~ 35 | If an argument is provided, set the Dock hiding animation effect to the effect indicated by effect number and return the (possibly new) effect number. If no argument is provided, then this function returns the current effect number. You can reference `hs._asm.undocumented.coredock.options.effect` to select the appropriate number for the desired effect or dereference the result. 36 | 37 | ~~~lua 38 | coredock.autoHide([bool]) -> bool 39 | ~~~ 40 | If an argument is provided, set the Dock Hiding state to on or off and return the (possibly new) hiding state. If no argument is provided, then this function returns the current hiding state. 41 | 42 | ~~~lua 43 | coredock.magnification([bool]) -> bool 44 | ~~~ 45 | If an argument is provided, set the Dock Magnification state to on or off and return the (possibly new) magnification state. If no argument is provided, then this function returns the current magnification state. 46 | 47 | ~~~lua 48 | coredock.magnificationSize([float]) -> float 49 | ~~~ 50 | If an argument is provided, set the Dock icon magnification size to a number between 0.0 and 1.0 and return the (possibly new) magnification size. If no argument is provided, then this function returns the current magnification size as a number between 0.0 and 1.0. 51 | 52 | ~~~lua 53 | coredock.orientation([orientation]) -> orientation 54 | ~~~ 55 | If an argument is provided, set the Dock orientation to the position indicated by orientation number and return the (possibly new) orientation number. If no argument is provided, then this function returns the current orientation number. You can reference `hs._asm.undocumented.coredock.options.orientation` to select the appropriate number for the desired orientation or dereference the result. 56 | 57 | ~~~lua 58 | coredock.pinning([pinning]) -> pinning 59 | ~~~ 60 | If an argument is provided, set the Dock pinning to the position indicated by pinning number and return the (possibly new) pinning number. If no argument is provided, then this function returns the current pinning number. You can reference `hs._asm.undocumented.coredock.options.pinning` to select the appropriate number for the desired pinning or dereference the result. 61 | 62 | ~~~lua 63 | coredock.restartDock() 64 | ~~~ 65 | This function restarts the user's Dock instance. This is not required for any of the functionality of this module, but does come in handy if your dock gets "misplaced" when you change monitor resolution or detach an external monitor (I've seen this occasionally when the Dock is on the left or right.) 66 | 67 | ~~~lua 68 | coredock.tileSize([float]) -> float 69 | ~~~ 70 | If an argument is provided, set the Dock icon tile size to a number between 0.0 and 1.0 and return the (possibly new) tile size. If no argument is provided, then this function returns the current tile size as a number between 0.0 and 1.0. 71 | 72 | ### Variables 73 | 74 | ~~~lua 75 | coredock.options[] 76 | ~~~ 77 | Connivence table of all currently defined coredock options. You can reference this by name to get the number required in the above functions or by number to get a human readable result from the number returned by the functions above. 78 | 79 | Note that the top orientation has not been supported even within the private APIs for some time and may disappear from here in a future release unless another solution can be found. 80 | * options.orientation[] -- an array of the orientation options available for `orientation` 81 | * top -- put the dock at the top of the monitor 82 | * bottom -- put the dock at the bottom of the monitor 83 | * left -- put the dock at the left of the monitor 84 | * right -- put the dock at the right of the monitor 85 | 86 | Note that dock pinning has not been supported even within the private APIs for some time and may disappear from here in a future release unless another solution can be found. 87 | * options.pinning[] -- an array of the pinning options available for `pinning` 88 | * start -- pin the dock at the start of its orientation 89 | * middle -- pin the dock at the middle of its orientation 90 | * end -- pin the dock at the end of its orientation 91 | 92 | Note that the suck animation is not displayed in the System Preferences panel correctly, but does remain in effect as long as you do not change this specific field while in the Preferences panel for the Dock. 93 | * options.effect[] -- an array of the dock animation options for `animation_effect` 94 | * genie -- use the genie animation 95 | * scale -- use the scale animation 96 | * suck -- use the suck animation 97 | 98 | 99 | ### License 100 | 101 | > Released under MIT license. 102 | > 103 | > Copyright (c) 2015 Aaron Magill 104 | > 105 | > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 106 | > 107 | > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 108 | > 109 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 110 | -------------------------------------------------------------------------------- /coredock/coredock-v0.1.1-universal.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asmagill/hammerspoon_asm.undocumented/85ab33aacdb000a609c7b6ddfa0eed415552ed59/coredock/coredock-v0.1.1-universal.tar.gz -------------------------------------------------------------------------------- /coredock/coredock.h: -------------------------------------------------------------------------------- 1 | // 2 | // CoreDockPrivate.h 3 | // Header file for undocumented Dock SPI 4 | // 5 | // Arranged by Tony Arnold 6 | // Based on CoreDockPrivate.h from http://www.cocoadev.com/index.pl?DockPrefsPrivate 7 | // 8 | // Contributors: 9 | // Alacatia Labs: Initial version posted at http://www.cocoadev.com/index.pl?DockPrefsPrivate 10 | // Tony Arnold: CoreDockGetWorkspacesEnabled, CoreDockSetWorkspacesEnabled, CoreDockSetWorkspacesCount 11 | // Steve Voida: CoreDockGetWorkspacesCount 12 | // 13 | // Changes: 14 | // 1.1 - Added attribution for Alacatia labs as originator 15 | // - Removed unnecessary reliance on CGSPrivate.h 16 | // 1.0 - Initial release 17 | 18 | typedef enum { 19 | kCoreDockOrientationIgnore = 0, 20 | kCoreDockOrientationTop = 1, 21 | kCoreDockOrientationBottom = 2, 22 | kCoreDockOrientationLeft = 3, 23 | kCoreDockOrientationRight = 4 24 | } CoreDockOrientation; 25 | 26 | typedef enum { 27 | kCoreDockPinningIgnore = 0, 28 | kCoreDockPinningStart = 1, 29 | kCoreDockPinningMiddle = 2, 30 | kCoreDockPinningEnd = 3 31 | } CoreDockPinning; 32 | 33 | typedef enum { 34 | kCoreDockEffectGenie = 1, 35 | kCoreDockEffectScale = 2, 36 | kCoreDockEffectSuck = 3 37 | } CoreDockEffect; 38 | 39 | // Tile size ranges from 0.0 to 1.0. 40 | extern float CoreDockGetTileSize(void); 41 | extern void CoreDockSetTileSize(float tileSize); 42 | 43 | extern void CoreDockGetOrientationAndPinning(CoreDockOrientation *outOrientation, CoreDockPinning *outPinning); 44 | // If you only want to set one, use 0 for the other. 45 | extern void CoreDockSetOrientationAndPinning(CoreDockOrientation orientation, CoreDockPinning pinning); 46 | 47 | extern void CoreDockGetEffect(CoreDockEffect *outEffect); 48 | extern void CoreDockSetEffect(CoreDockEffect effect); 49 | 50 | extern Boolean CoreDockGetAutoHideEnabled(void); 51 | extern void CoreDockSetAutoHideEnabled(Boolean flag); 52 | 53 | extern Boolean CoreDockIsMagnificationEnabled(void); 54 | extern void CoreDockSetMagnificationEnabled(Boolean flag); 55 | 56 | // Magnification ranges from 0.0 to 1.0. 57 | extern float CoreDockGetMagnificationSize(void); 58 | extern void CoreDockSetMagnificationSize(float newSize); 59 | 60 | extern Boolean CoreDockGetWorkspacesEnabled(void); 61 | extern void CoreDockSetWorkspacesEnabled(Boolean); // This works, but wipes out all of the other spaces prefs. An alternative is to use the ScriptingBridge which works just fine. 62 | 63 | extern void CoreDockGetWorkspacesCount(int *rows, int *cols); 64 | extern void CoreDockSetWorkspacesCount(int rows, int cols); 65 | -------------------------------------------------------------------------------- /coredock/init.lua: -------------------------------------------------------------------------------- 1 | --- === hs._asm.undocumented.coredock === 2 | --- 3 | --- This module provides access to CoreDock related features. This allows you to adjust the Dock's position, pinning, hiding, magnification and animation settings. 4 | --- 5 | --- This module utilizes undocumented or unpublished functions to manipulate options and features within OS X. These are from "private" api's for Mac OS X and are not guaranteed to work with any particular version of OS X or at all.This code was based primarily on code samples and segments found at (https://code.google.com/p/undocumented-goodness/) and (https://code.google.com/p/iterm2/source/browse/branches/0.10.x/CGSInternal/CGSDebug.h?r=2). 6 | --- 7 | --- I make no promises that these will work for you or work at all with any, past, current, or future versions of OS X. I can confirm only that they didn't crash my machine during testing under 10.10. You have been warned. 8 | --- 9 | --- Note that the top orientation and dock pinning has not been supported even within the private APIs for some time and may disappear from here in a future release unless another solution can be found. It is provided here for testing and to encourage suggestions if someone is aware of a solution that has not yet been tried. 10 | 11 | local USERDATA_TAG = "hs._asm.undocumented.coredock" 12 | local module = require(USERDATA_TAG..".internal") 13 | 14 | local basePath = package.searchpath(USERDATA_TAG, package.path) 15 | if basePath then 16 | basePath = basePath:match("^(.+)/init.lua$") 17 | if require"hs.fs".attributes(basePath .. "/docs.json") then 18 | require"hs.doc".registerJSONFile(basePath .. "/docs.json") 19 | end 20 | end 21 | 22 | -- local log = require("hs.logger").new(USERDATA_TAG, require"hs.settings".get(USERDATA_TAG .. ".logLevel") or "warning") 23 | 24 | -- private variables and methods ----------------------------------------- 25 | 26 | -- Public interface ------------------------------------------------------ 27 | 28 | module.options = ls.makeConstantsTable(module.options) 29 | 30 | --- hs._asm.undocumented.coredock.restartDock() 31 | --- Function 32 | --- This function restarts the user's Dock instance. This is not required for any of the functionality of this module, but does come in handy if your dock gets "misplaced" when you change monitor resolution or detach an external monitor (I've seen this occasionally when the Dock is on the left or right.) 33 | function module.restartDock() 34 | os.execute("/usr/bin/killall Dock") 35 | end 36 | 37 | -- Return Module Object -------------------------------------------------- 38 | 39 | return module 40 | -------------------------------------------------------------------------------- /coredock/internal.m: -------------------------------------------------------------------------------- 1 | @import Cocoa ; 2 | @import LuaSkin ; 3 | #import "coredock.h" 4 | 5 | static const char *USERDATA_TAG = "hs._asm.undocumented.coredock" ; 6 | 7 | static LSRefTable refTable = LUA_NOREF ; 8 | 9 | /// hs._asm.undocumented.coredock.tileSize([size]) -> float 10 | /// Function 11 | /// Get or set the Dock icon tile size as a number between 0.0 and 1.0. 12 | /// 13 | /// Parameters: 14 | /// * size - an optional number between 0.0 and 1.0 to set the Dock icon tile size to. 15 | /// 16 | /// Returns: 17 | /// * the (possibly changed) current value 18 | static int coredock_tilesize(lua_State* L) { 19 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 20 | [skin checkArgs:LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK] ; 21 | 22 | if (!lua_isnone(L, 1)) { 23 | float tileSize = (float) luaL_checknumber(L, -1) ; 24 | if (tileSize >= 0 && tileSize <= 1) 25 | CoreDockSetTileSize(tileSize) ; 26 | else 27 | return luaL_error(L,"tilesize must be a number between 0.0 and 1.0") ; 28 | } 29 | lua_pushnumber(L, (lua_Number)CoreDockGetTileSize()) ; 30 | return 1 ; 31 | } 32 | 33 | /// hs._asm.undocumented.coredock.magnificationSize([size]) -> float 34 | /// Function 35 | /// Get or set the Dock icon magnification size as a number between 0.0 and 1.0. 36 | /// 37 | /// Parameters: 38 | /// * size - an optional number between 0.0 and 1.0 to set the Dock icon magnification size to. 39 | /// 40 | /// Returns: 41 | /// * the (possibly changed) current value 42 | static int coredock_magnification_size(lua_State* L) { 43 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 44 | [skin checkArgs:LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK] ; 45 | 46 | if (!lua_isnone(L, 1)) { 47 | float magSize = (float) luaL_checknumber(L, -1) ; 48 | if (magSize >= 0 && magSize <= 1) 49 | CoreDockSetMagnificationSize(magSize) ; 50 | else 51 | return luaL_error(L,"magnification_size must be a number between 0.0 and 1.0") ; 52 | } 53 | lua_pushnumber(L, (lua_Number)CoreDockGetMagnificationSize()) ; 54 | return 1 ; 55 | } 56 | 57 | // /// hs._asm.undocumented.coredock.oandp(orientation, pinning) 58 | // /// Function 59 | // /// Sets the Dock orientation and pinning simultaneously to the placement indicated by orientation and pinning. 60 | // static int coredock_oandp(lua_State* L) { 61 | // CoreDockOrientation ourOrientation = luaL_checkinteger(L, -2) ; 62 | // CoreDockPinning ourPinning = luaL_checkinteger(L, -1) ; 63 | // 64 | // CoreDockSetOrientationAndPinning(ourOrientation, ourPinning) ; 65 | // return 0 ; 66 | // } 67 | 68 | /// hs._asm.undocumented.coredock.orientation([orientation]) -> orientation 69 | /// Function 70 | /// Get or set the Dock orientation. 71 | /// 72 | /// Parameters: 73 | /// * orientation - an integer as specified in `hs._asm.undocumented.coredock.options.orientation` 74 | /// 75 | /// Returns: 76 | /// * the (possibly changed) current value 77 | /// 78 | /// Notes: 79 | /// * the top orientation and dock pinning has not been supported even within the private APIs for some time and may disappear from here in a future release unless another solution can be found. It is provided here for testing and to encourage suggestions if someone is aware of a solution that has not yet been tried. 80 | static int coredock_orientation(lua_State* L) { 81 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 82 | [skin checkArgs:LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK] ; 83 | 84 | if (!lua_isnone(L, 1)) { 85 | CoreDockOrientation ourOrientation = (CoreDockOrientation)(luaL_checkinteger(L, -1)) ; 86 | CoreDockPinning ourPinning = kCoreDockPinningIgnore ; 87 | CoreDockSetOrientationAndPinning(ourOrientation, ourPinning) ; 88 | } 89 | CoreDockOrientation ourOrientation ; 90 | CoreDockPinning ourPinning ; 91 | CoreDockGetOrientationAndPinning(&ourOrientation, &ourPinning) ; 92 | lua_pushinteger(L, (int) ourOrientation) ; 93 | return 1 ; 94 | } 95 | 96 | /// hs._asm.undocumented.coredock.pinning([pinning]) -> pinning 97 | /// Function 98 | /// Get or set the Dock pinning. 99 | /// 100 | /// Parameters: 101 | /// * pinning - an integer as specified in `hs._asm.undocumented.coredock.options.pinning` 102 | /// 103 | /// Returns: 104 | /// * the (possibly changed) current value 105 | /// 106 | /// Notes: 107 | /// * the top orientation and dock pinning has not been supported even within the private APIs for some time and may disappear from here in a future release unless another solution can be found. It is provided here for testing and to encourage suggestions if someone is aware of a solution that has not yet been tried. 108 | static int coredock_pinning(lua_State* L) { 109 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 110 | [skin checkArgs:LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK] ; 111 | 112 | if (!lua_isnone(L, 1)) { 113 | CoreDockOrientation ourOrientation = kCoreDockOrientationIgnore ; 114 | CoreDockPinning ourPinning = (CoreDockPinning)(luaL_checkinteger(L, -1)) ; 115 | CoreDockSetOrientationAndPinning(ourOrientation, ourPinning) ; 116 | } 117 | CoreDockOrientation ourOrientation ; 118 | CoreDockPinning ourPinning ; 119 | CoreDockGetOrientationAndPinning(&ourOrientation, &ourPinning) ; 120 | lua_pushinteger(L, (int) ourPinning) ; 121 | return 1 ; 122 | } 123 | 124 | 125 | /// hs._asm.undocumented.coredock.magnification([state]) -> bool 126 | /// Function 127 | /// Get or set whether or not the Dock Magnification is enabled. 128 | /// 129 | /// Parameters: 130 | /// * state - an optional boolean value specifying whether or not Dock Magnification should be enabled. 131 | /// 132 | /// Returns: 133 | /// * the (possibly changed) current value 134 | static int coredock_magnification(lua_State* L) { 135 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 136 | [skin checkArgs:LS_TBOOLEAN | LS_TOPTIONAL, LS_TBREAK] ; 137 | 138 | if (!lua_isnone(L, 1)) { 139 | CoreDockSetMagnificationEnabled((Boolean) lua_toboolean(L, -1)) ; 140 | } 141 | if (CoreDockIsMagnificationEnabled()) lua_pushboolean(L, YES) ; else lua_pushboolean(L, NO) ; 142 | return 1 ; 143 | } 144 | 145 | /// hs._asm.undocumented.coredock.autoHide([state]) -> bool 146 | /// Function 147 | /// Get or set whether or not Dock Hiding is enabled. 148 | /// 149 | /// Parameters: 150 | /// * state - an optional boolean value specifying whether or not Dock Hiding should be enabled. 151 | /// 152 | /// Returns: 153 | /// * the (possibly changed) current value 154 | static int coredock_autohide(lua_State* L) { 155 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 156 | [skin checkArgs:LS_TBOOLEAN | LS_TOPTIONAL, LS_TBREAK] ; 157 | 158 | if (!lua_isnone(L, 1)) { 159 | CoreDockSetAutoHideEnabled((Boolean) lua_toboolean(L, -1)) ; 160 | } 161 | if (CoreDockGetAutoHideEnabled()) lua_pushboolean(L, YES) ; else lua_pushboolean(L, NO) ; 162 | return 1 ; 163 | } 164 | 165 | /// hs._asm.undocumented.coredock.animationEffect([effect]) -> effect 166 | /// Function 167 | /// Get or set the Dock pinning. 168 | /// 169 | /// Parameters: 170 | /// * effect - an integer as specified in `hs._asm.undocumented.coredock.options.effect` 171 | /// 172 | /// Returns: 173 | /// * the (possibly changed) current value 174 | static int coredock_animationeffect(lua_State* L) { 175 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 176 | [skin checkArgs:LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK] ; 177 | 178 | if (!lua_isnone(L, 1)) { 179 | CoreDockEffect ourEffect = (CoreDockEffect)(luaL_checkinteger(L, -1)) ; 180 | CoreDockSetEffect(ourEffect) ; 181 | } 182 | CoreDockEffect ourEffect ; 183 | CoreDockGetEffect(&ourEffect) ; 184 | lua_pushinteger(L, (int) ourEffect) ; 185 | return 1 ; 186 | } 187 | 188 | /// hs._asm.undocumented.coredock.options[] 189 | /// Variable 190 | /// Connivence array of all currently defined coredock options. 191 | /// 192 | /// Note that the top orientation has not been supported even within the private APIs for some time and may disappear from here in a future release unless another solution can be found. 193 | /// * options.orientation[] -- an array of the orientation options available for `orientation` 194 | /// * top -- put the dock at the top of the monitor 195 | /// * bottom -- put the dock at the bottom of the monitor 196 | /// * left -- put the dock at the left of the monitor 197 | /// * right -- put the dock at the right of the monitor 198 | /// 199 | /// Note that dock pinning has not been supported even within the private APIs for some time and may disappear from here in a future release unless another solution can be found. 200 | /// * options.pinning[] -- an array of the pinning options available for `pinning` 201 | /// * start -- pin the dock at the start of its orientation 202 | /// * middle -- pin the dock at the middle of its orientation 203 | /// * end -- pin the dock at the end of its orientation 204 | /// 205 | /// Note that the suck animation is not displayed in the System Preferences panel correctly, but does remain in effect as long as you do not change this specific field while in the Preferences panel for the Dock. 206 | /// * options.effect[] -- an array of the dock animation options for `animation_effect` 207 | /// * genie -- use the genie animation 208 | /// * scale -- use the scale animation 209 | /// * suck -- use the suck animation 210 | /// 211 | /// Notes: 212 | /// * the top orientation and dock pinning has not been supported even within the private APIs for some time and may disappear from here in a future release unless another solution can be found. It is provided here for testing and to encourage suggestions if someone is aware of a solution that has not yet been tried. 213 | static void coredock_options (lua_State *L) { 214 | lua_newtable(L) ; 215 | lua_newtable(L) ; 216 | lua_pushinteger(L, kCoreDockOrientationTop) ; lua_setfield(L, -2, "top") ; 217 | lua_pushinteger(L, kCoreDockOrientationBottom) ; lua_setfield(L, -2, "bottom") ; 218 | lua_pushinteger(L, kCoreDockOrientationLeft) ; lua_setfield(L, -2, "left") ; 219 | lua_pushinteger(L, kCoreDockOrientationRight) ; lua_setfield(L, -2, "right") ; 220 | lua_setfield(L, -2, "orientation") ; 221 | lua_newtable(L) ; 222 | lua_pushinteger(L, kCoreDockPinningStart) ; lua_setfield(L, -2, "start") ; 223 | lua_pushinteger(L, kCoreDockPinningMiddle) ; lua_setfield(L, -2, "middle") ; 224 | lua_pushinteger(L, kCoreDockPinningEnd) ; lua_setfield(L, -2, "end") ; 225 | lua_setfield(L, -2, "pinning") ; 226 | lua_newtable(L) ; 227 | lua_pushinteger(L, kCoreDockEffectGenie) ; lua_setfield(L, -2, "genie") ; 228 | lua_pushinteger(L, kCoreDockEffectScale) ; lua_setfield(L, -2, "scale") ; 229 | lua_pushinteger(L, kCoreDockEffectSuck) ; lua_setfield(L, -2, "suck") ; 230 | lua_setfield(L, -2, "effect") ; 231 | } 232 | 233 | static const luaL_Reg moduleLib[] = { 234 | {"tileSize", coredock_tilesize}, 235 | {"orientation", coredock_orientation}, 236 | {"pinning", coredock_pinning}, 237 | {"animationEffect", coredock_animationeffect}, 238 | {"autoHide", coredock_autohide}, 239 | {"magnification", coredock_magnification}, 240 | {"magnificationSize", coredock_magnification_size}, 241 | {NULL, NULL} 242 | } ; 243 | 244 | int luaopen_hs__asm_undocumented_coredock_internal(lua_State* L) { 245 | LuaSkin *skin = [LuaSkin sharedWithState:L] ; 246 | refTable = [skin registerLibrary:USERDATA_TAG functions:moduleLib metaFunctions:nil] ; 247 | 248 | coredock_options(L) ; lua_setfield(L, -2, "options") ; 249 | return 1 ; 250 | } 251 | -------------------------------------------------------------------------------- /cursor/CGSConnection.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Alacatia Labs 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | * 20 | * Joe Ranieri joe@alacatia.com 21 | * 22 | */ 23 | 24 | // 25 | // Updated by Robert Widmann. 26 | // Copyright © 2015 CodaFi. All rights reserved. 27 | // Released under the MIT license. 28 | // 29 | 30 | #ifndef CGS_CONNECTION_INTERNAL_H 31 | #define CGS_CONNECTION_INTERNAL_H 32 | 33 | /// The type of connections to the Window Server. 34 | /// 35 | /// Every application is given a singular connection ID through which it can receieve and manipulate 36 | /// values, state, notifications, events, etc. in the Window Server. It 37 | typedef int CGSConnectionID; 38 | 39 | typedef void *CGSNotificationData; 40 | typedef void *CGSNotificationArg; 41 | typedef int CGSTransitionID; 42 | 43 | 44 | #pragma mark - Connection Lifecycle 45 | 46 | 47 | /// Gets the default connection for this process. 48 | CG_EXTERN CGSConnectionID CGSMainConnectionID(void); 49 | 50 | /// Creates a new connection to the Window Server. 51 | CG_EXTERN CGError CGSNewConnection(int unused, CGSConnectionID *outConnection); 52 | 53 | /// Releases a CGSConnection and all CGSWindows owned by it. 54 | CG_EXTERN CGError CGSReleaseConnection(CGSConnectionID cid); 55 | 56 | /// Gets the default connection for the current thread. 57 | CG_EXTERN CGSConnectionID CGSDefaultConnectionForThread(void); 58 | 59 | /// Gets the pid of the process that owns this connection to the Window Server. 60 | CG_EXTERN CGError CGSConnectionGetPID(CGSConnectionID cid, pid_t *outPID); 61 | 62 | /// Gets the connection for the given process serial number. 63 | CG_EXTERN CGError CGSGetConnectionIDForPSN(CGSConnectionID cid, const ProcessSerialNumber *psn, CGSConnectionID *outOwnerCID); 64 | 65 | /// Returns whether the menu bar exists for the given connection ID. 66 | /// 67 | /// For the majority of applications, this function should return true. But at system updates, 68 | /// initialization, and shutdown, the menu bar will be either initially gone then created or 69 | /// hidden and then destroyed. 70 | CG_EXTERN bool CGSMenuBarExists(CGSConnectionID cid); 71 | 72 | /// Closes ALL connections to the Window Server by the current application. 73 | /// 74 | /// The application is effectively turned into a Console-based application after the invocation of 75 | /// this method. 76 | CG_EXTERN CGError CGSShutdownServerConnections(void); 77 | 78 | 79 | #pragma mark - Connection Properties 80 | 81 | 82 | /// Retrieves the value associated with the given key for the given connection. 83 | /// 84 | /// This method is structured so processes can send values through the Window Server to other 85 | /// processes - assuming they know each others connection IDs. The recommended use case for this 86 | /// function appears to be keeping state around for application-level sub-connections. 87 | CG_EXTERN CGError CGSCopyConnectionProperty(CGSConnectionID cid, CGSConnectionID targetCID, CFStringRef key, CFTypeRef *outValue); 88 | 89 | /// Associates a value for the given key on the given connection. 90 | CG_EXTERN CGError CGSSetConnectionProperty(CGSConnectionID cid, CGSConnectionID targetCID, CFStringRef key, CFTypeRef value); 91 | 92 | 93 | #pragma mark - Connection Updates 94 | 95 | 96 | /// Disables updates on a connection 97 | /// 98 | /// Calls to disable updates nest much like `-beginUpdates`/`-endUpdates`. the Window Server will 99 | /// forcibly reenable updates after 1 second if you fail to invoke `CGSReenableUpdate`. 100 | CG_EXTERN CGError CGSDisableUpdate(CGSConnectionID cid); 101 | 102 | /// Re-enables updates on a connection. 103 | /// 104 | /// Calls to enable updates nest much like `-beginUpdates`/`-endUpdates`. 105 | CG_EXTERN CGError CGSReenableUpdate(CGSConnectionID cid); 106 | 107 | 108 | #pragma mark - System-Level Notification Registration 109 | 110 | 111 | typedef enum { 112 | kCGSNotificationDebugOptionsChanged = 200, 113 | 114 | kCGSNotificationMouseMoved = 715, 115 | 116 | kCGSNotificationTrackingRegionEntered = 718, 117 | kCGSNotificationTrackingRegionExited = 719, 118 | 119 | // 724 - keyboard preferences changed 120 | 121 | // 729, 730 seem to be process deactivated / activated - but only for this process 122 | // 731 seems to be this process hidden or shown 123 | 124 | // kCGSNotificationAppUnresponsive = 750, 125 | // kCGSNotificationAppResponsive = 751, 126 | 127 | // 761 - hotkey disabled 128 | // 762 - hotkey enabled (do these two fire twice?) 129 | 130 | // 763 - hotkey begins editing 131 | // 764 - hotkey ends editing 132 | 133 | // 765, 766 seem to be about the hotkey state (all disabled, etc) 134 | 135 | kCGSNotificationWorkspaceChanged = 1401, 136 | 137 | kCGSNotificationTransitionEnded = 1700, 138 | } CGSNotificationType; 139 | 140 | typedef void (*CGSNotifyProcPtr)(CGSNotificationType type, void *data, unsigned int dataLength, void *userData); 141 | 142 | /// Registers a function to receive notifications for system-wide events. 143 | CG_EXTERN CGError CGSRegisterNotifyProc(CGSNotifyProcPtr proc, CGSNotificationType type, void *userData); 144 | 145 | /// Unregisters a function that was registered to receive notifications for system-wide events. 146 | CG_EXTERN CGError CGSRemoveNotifyProc(CGSNotifyProcPtr proc, CGSNotificationType type, void *userData); 147 | 148 | 149 | #pragma mark - Application-Level Notification Registration 150 | 151 | 152 | typedef enum { 153 | kCGSScreenResolutionChangedEvent = 100, 154 | kCGSScreenDisplayParametersChangedEvent = 101, 155 | kCGSClientEnterFullscreen = 106, 156 | kCGSClientExitFullscreen = 107, 157 | kCGSScreenAcceleratorChangedEvent = 121, 158 | kCGSNotificationAppUnresponsive = 750, 159 | kCGSNotificationAppResponsive = 751, 160 | kCGSWorkspaceConfigurationDisabledEvent = 761, 161 | kCGSWorkspaceConfigurationEnabledEvent = 762, 162 | kCGSWindowDidBecomeUnoccludedEvent = 912, 163 | kCGSWindowDidBecomeOccludedEvent = 913, 164 | kCGSWindowWasMovedByDockEvent = 1205, 165 | kCGSWindowWasResizedByDockEvent = 1207, 166 | kCGSWindowDidBecomeManagedByDockEvent = 1208, 167 | kCGSWindowTileSpaceBeganLiveResize = 1312, 168 | kCGSWindowTileSpaceEndedLiveResize = 1313, 169 | kCGSWindowTileSpaceDidResize = 1314, 170 | kCGSWorkspaceChangedEvent = 1401, 171 | } CGSConnectionNotifyEvent; 172 | 173 | typedef void (*CGConnectionNotifyProc)(CGSNotificationType type, CGSNotificationData notificationData, size_t dataLength, CGSNotificationArg userParameter, CGSConnectionID); 174 | 175 | /// Registers a function to receive notifications for connection-level events. 176 | CG_EXTERN CGError CGSRegisterConnectionNotifyProc(CGSConnectionID cid, CGConnectionNotifyProc function, CGSConnectionNotifyEvent event, void *userData); 177 | 178 | /// Unregisters a function that was registered to receive notifications for connection-level events. 179 | CG_EXTERN CGError CGSRemoveConnectionNotifyProc(CGSConnectionID cid, CGConnectionNotifyProc function, CGSConnectionNotifyEvent event, void *userData); 180 | 181 | 182 | typedef void (*CGSNewConnectionNotificationProc)(CGSConnectionID cid); 183 | 184 | /// Registers a function that gets invoked when the application's connection ID is created by the 185 | /// Window Server. 186 | CG_EXTERN CGError CGSRegisterForNewConnectionNotification(CGSNewConnectionNotificationProc proc); 187 | 188 | /// Removes a function that was registered to receive notifications for the creation of the 189 | /// application's connection to the Window Server. 190 | CG_EXTERN CGError CGSRemoveNewConnectionNotification(CGSNewConnectionNotificationProc proc); 191 | 192 | typedef void (*CGSConnectionDeathNotificationProc)(CGSConnectionID cid); 193 | 194 | /// Registers a function that gets invoked when the application's connection ID is destroyed - 195 | /// ideally by the Window Server. 196 | /// 197 | /// Connection death is supposed to be a fatal event that is only triggered when the application 198 | /// terminates or when you have explicitly destroyed a sub-connection to the Window Server. 199 | CG_EXTERN CGError CGSRegisterForConnectionDeathNotification(CGSConnectionDeathNotificationProc proc); 200 | 201 | /// Removes a function that was registered to receive notifications for the destruction of the 202 | /// application's connection to the Window Server. 203 | CG_EXTERN CGError CGSRemoveConnectionDeathNotification(CGSConnectionDeathNotificationProc proc); 204 | 205 | 206 | #pragma mark - Miscellaneous Security Holes 207 | 208 | /// Sets a "Universal Owner" for the connection ID. Currently, that owner is Dock.app, which needs 209 | /// control over the window to provide system features like hiding and showing windows, moving them 210 | /// around, etc. 211 | /// 212 | /// Because the Universal Owner owns every window under this connection, it can manipulate them 213 | /// all as it sees fit. If you can beat the dock, you have total control over the process' 214 | /// connection. 215 | CG_EXTERN CGError CGSSetUniversalOwner(CGSConnectionID cid); 216 | 217 | /// Assuming you have the connection ID of the current universal owner, or are said universal owner, 218 | /// allows you to specify another connection that has total control over the application's windows. 219 | CG_EXTERN CGError CGSSetOtherUniversalConnection(CGSConnectionID cid, CGSConnectionID otherConnection); 220 | 221 | /// Sets the given connection ID as the login window connection ID. Windows for the application are 222 | /// then brought to the fore when the computer logs off or goes to sleep. 223 | /// 224 | /// Why this is still here, I have no idea. Window Server only accepts one process calling this 225 | /// ever. If you attempt to invoke this after loginwindow does you will be yelled at and nothing 226 | /// will happen. If you can manage to beat loginwindow, however, you know what they say: 227 | /// 228 | /// When you teach a man to phish... 229 | CG_EXTERN CGError CGSSetLoginwindowConnection(CGSConnectionID cid) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER; 230 | 231 | //! The data sent with kCGSNotificationAppUnresponsive and kCGSNotificationAppResponsive. 232 | typedef struct { 233 | #if __BIG_ENDIAN__ 234 | uint16_t majorVersion; 235 | uint16_t minorVersion; 236 | #else 237 | uint16_t minorVersion; 238 | uint16_t majorVersion; 239 | #endif 240 | 241 | //! The length of the entire notification. 242 | uint32_t length; 243 | 244 | CGSConnectionID cid; 245 | pid_t pid; 246 | ProcessSerialNumber psn; 247 | } CGSProcessNotificationData; 248 | 249 | //! The data sent with kCGSNotificationDebugOptionsChanged. 250 | typedef struct { 251 | int newOptions; 252 | int unknown[2]; // these two seem to be zero 253 | } CGSDebugNotificationData; 254 | 255 | //! The data sent with kCGSNotificationTransitionEnded 256 | typedef struct { 257 | CGSTransitionID transition; 258 | } CGSTransitionNotificationData; 259 | 260 | #endif /* CGS_CONNECTION_INTERNAL_H */ 261 | -------------------------------------------------------------------------------- /cursor/CGSCursor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Alacatia Labs 3 | * 4 | * This software is provided 'as-is', without any express or implied 5 | * warranty. In no event will the authors be held liable for any damages 6 | * arising from the use of this software. 7 | * 8 | * Permission is granted to anyone to use this software for any purpose, 9 | * including commercial applications, and to alter it and redistribute it 10 | * freely, subject to the following restrictions: 11 | * 12 | * 1. The origin of this software must not be misrepresented; you must not 13 | * claim that you wrote the original software. If you use this software 14 | * in a product, an acknowledgment in the product documentation would be 15 | * appreciated but is not required. 16 | * 2. Altered source versions must be plainly marked as such, and must not be 17 | * misrepresented as being the original software. 18 | * 3. This notice may not be removed or altered from any source distribution. 19 | * 20 | * Joe Ranieri joe@alacatia.com 21 | * 22 | */ 23 | 24 | // 25 | // Updated by Robert Widmann. 26 | // Copyright © 2015 CodaFi. All rights reserved. 27 | // Released under the MIT license. 28 | // 29 | 30 | #ifndef CGS_CURSOR_INTERNAL_H 31 | #define CGS_CURSOR_INTERNAL_H 32 | 33 | #include "CGSConnection.h" 34 | 35 | typedef enum : NSInteger { 36 | CGSCursorArrow = 0, 37 | CGSCursorIBeam = 1, 38 | CGSCursorIBeamXOR = 2, 39 | CGSCursorAlias = 3, 40 | CGSCursorCopy = 4, 41 | CGSCursorMove = 5, 42 | CGSCursorArrowContext = 6, 43 | CGSCursorWait = 7, 44 | CGSCursorEmpty = 8, 45 | } CGSCursorID; 46 | 47 | 48 | /// Registers a cursor with the given properties. 49 | /// 50 | /// - Parameter cid: The connection ID to register with. 51 | /// - Parameter cursorName: The system-wide name the cursor will be registered under. 52 | /// - Parameter setGlobally: Whether the cursor registration can appear system-wide. 53 | /// - Parameter instantly: Whether the registration of cursor images should occur immediately. Passing false 54 | /// may speed up the call. 55 | /// - Parameter frameCount: The number of images in the cursor image array. 56 | /// - Parameter imageArray: An array of CGImageRefs that are used to display the cursor. Multiple images in 57 | /// conjunction with a non-zero `frameDuration` cause animation. 58 | /// - Parameter cursorSize: The size of the cursor's images. Recommended size is 16x16 points 59 | /// - Parameter hotspot: The location touch events will emanate from. 60 | /// - Parameter seed: The seed for the cursor's registration. 61 | /// - Parameter bounds: The total size of the cursor. 62 | /// - Parameter frameDuration: How long each image will be displayed for. 63 | /// - Parameter repeatCount: Number of times the cursor should repeat cycling its image frames. 64 | CG_EXTERN CGError CGSRegisterCursorWithImages(CGSConnectionID cid, 65 | const char *cursorName, 66 | bool setGlobally, bool instantly, 67 | NSUInteger frameCount, CFArrayRef imageArray, 68 | CGSize cursorSize, CGPoint hotspot, 69 | int *seed, 70 | CGRect bounds, CGFloat frameDuration, 71 | NSInteger repeatCount); 72 | 73 | 74 | #pragma mark - Cursor Registration 75 | 76 | 77 | /// Copies the size of data associated with the cursor registered under the given name. 78 | CG_EXTERN CGError CGSGetRegisteredCursorDataSize(CGSConnectionID cid, const char *cursorName, size_t *outDataSize); 79 | 80 | /// Re-assigns the given cursor name to the cursor represented by the given seed value. 81 | CG_EXTERN CGError CGSSetRegisteredCursor(CGSConnectionID cid, const char *cursorName, int *cursorSeed); 82 | 83 | /// Copies the properties out of the cursor registered under the given name. 84 | CG_EXTERN CGError CGSCopyRegisteredCursorImages(CGSConnectionID cid, const char *cursorName, CGSize *imageSize, CGPoint *hotSpot, NSUInteger *frameCount, CGFloat *frameDuration, CFArrayRef *imageArray); 85 | 86 | /// Re-assigns one of the system-defined cursors to the cursor represented by the given seed value. 87 | CG_EXTERN void CGSSetSystemDefinedCursorWithSeed(CGSConnectionID connection, CGSCursorID systemCursor, int *cursorSeed); 88 | 89 | 90 | #pragma mark - Cursor Display 91 | 92 | 93 | /// Shows the cursor. 94 | CG_EXTERN CGError CGSShowCursor(CGSConnectionID cid); 95 | 96 | /// Hides the cursor. 97 | CG_EXTERN CGError CGSHideCursor(CGSConnectionID cid); 98 | 99 | /// Hides the cursor until the cursor is moved. 100 | CG_EXTERN CGError CGSObscureCursor(CGSConnectionID cid); 101 | 102 | /// Acts as if a mouse moved event occured and that reveals the cursor if it was hidden. 103 | CG_EXTERN CGError CGSRevealCursor(CGSConnectionID cid); 104 | 105 | /// Shows or hides the spinning beachball of death. 106 | /// 107 | /// If you call this, I hate you. 108 | CG_EXTERN CGError CGSForceWaitCursorActive(CGSConnectionID cid, bool showWaitCursor); 109 | 110 | /// Unconditionally sets the location of the cursor on the screen to the given coordinates. 111 | CG_EXTERN CGError CGSWarpCursorPosition(CGSConnectionID cid, CGFloat x, CGFloat y); 112 | 113 | 114 | #pragma mark - Cursor Properties 115 | 116 | 117 | /// Gets the current cursor's seed value. 118 | /// 119 | /// Every time the cursor is updated, the seed changes. 120 | CG_EXTERN int CGSCurrentCursorSeed(void); 121 | 122 | /// Gets the current location of the cursor relative to the screen's coordinates. 123 | CG_EXTERN CGError CGSGetCurrentCursorLocation(CGSConnectionID cid, CGPoint *outPos); 124 | 125 | /// Gets the name (ideally in reverse DNS form) of a system cursor. 126 | CG_EXTERN char *CGSCursorNameForSystemCursor(CGSCursorID cursor); 127 | 128 | /// Gets the scale of the current currsor. 129 | CG_EXTERN CGError CGSGetCursorScale(CGSConnectionID cid, CGFloat *outScale); 130 | 131 | /// Sets the scale of the current cursor. 132 | /// 133 | /// The largest the Universal Access prefpane allows you to go is 4.0. 134 | CG_EXTERN CGError CGSSetCursorScale(CGSConnectionID cid, CGFloat scale); 135 | 136 | 137 | #pragma mark - Cursor Data 138 | 139 | 140 | /// Gets the size of the data for the connection's cursor. 141 | CG_EXTERN CGError CGSGetCursorDataSize(CGSConnectionID cid, size_t *outDataSize); 142 | 143 | /// Gets the data for the connection's cursor. 144 | CG_EXTERN CGError CGSGetCursorData(CGSConnectionID cid, void *outData); 145 | 146 | /// Gets the size of the data for the current cursor. 147 | CG_EXTERN CGError CGSGetGlobalCursorDataSize(CGSConnectionID cid, size_t *outDataSize); 148 | 149 | /// Gets the data for the current cursor. 150 | CG_EXTERN CGError CGSGetGlobalCursorData(CGSConnectionID cid, void *outData, int *outDataSize, int *outRowBytes, CGRect *outRect, CGPoint *outHotSpot, int *outDepth, int *outComponents, int *outBitsPerComponent); 151 | 152 | /// Gets the size of data for a system-defined cursor. 153 | CG_EXTERN CGError CGSGetSystemDefinedCursorDataSize(CGSConnectionID cid, CGSCursorID cursor, size_t *outDataSize); 154 | 155 | /// Gets the data for a system-defined cursor. 156 | CG_EXTERN CGError CGSGetSystemDefinedCursorData(CGSConnectionID cid, CGSCursorID cursor, void *outData, int *outRowBytes, CGRect *outRect, CGPoint *outHotSpot, int *outDepth, int *outComponents, int *outBitsPerComponent); 157 | 158 | #endif /* CGS_CURSOR_INTERNAL_H */ 159 | -------------------------------------------------------------------------------- /cursor/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Aaron Magill 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /cursor/Makefile: -------------------------------------------------------------------------------- 1 | mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) 2 | current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) 3 | 4 | MODULE := $(current_dir) 5 | PREFIX ?= ~/.hammerspoon 6 | HS_APPLICATION ?= /Applications 7 | 8 | OBJCFILE = ${wildcard *.m} 9 | LUAFILE = ${wildcard *.lua} 10 | HEADERS = ${wildcard *.h} 11 | 12 | SOFILE := $(OBJCFILE:.m=.so) 13 | DEBUG_CFLAGS ?= -g 14 | DOC_FILE = hs._asm.undocumented.$(MODULE).json 15 | 16 | # special vars for uninstall 17 | space := 18 | space += 19 | comma := , 20 | ALLFILES := $(LUAFILE) 21 | ALLFILES += $(SOFILE) 22 | 23 | .SUFFIXES: .m .so 24 | 25 | #CC=cc 26 | CC=clang 27 | EXTRA_CFLAGS ?= -Wconversion -Wdeprecated -F$(HS_APPLICATION)/Hammerspoon.app/Contents/Frameworks 28 | CFLAGS += $(DEBUG_CFLAGS) -fobjc-arc -DHS_EXTERNAL_MODULE -Wall -Wextra $(EXTRA_CFLAGS) 29 | LDFLAGS += -dynamiclib -undefined dynamic_lookup $(EXTRA_LDFLAGS) 30 | 31 | DOC_SOURCES = $(LUAFILE) $(OBJCFILE) 32 | 33 | all: verify $(SOFILE) 34 | 35 | .m.so: $(HEADERS) 36 | $(CC) $< $(CFLAGS) $(LDFLAGS) -o $@ 37 | 38 | install: verify install-objc install-lua 39 | 40 | verify: $(LUAFILE) 41 | luac -p $(LUAFILE) && echo "Passed" 42 | 43 | install-objc: $(SOFILE) 44 | mkdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE) 45 | install -m 0644 $(SOFILE) $(PREFIX)/hs/_asm/undocumented/$(MODULE) 46 | cp -vpR $(OBJCFILE:.m=.so.dSYM) $(PREFIX)/hs/_asm/undocumented/$(MODULE) 47 | 48 | install-lua: $(LUAFILE) 49 | mkdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE) 50 | install -m 0644 $(LUAFILE) $(PREFIX)/hs/_asm/undocumented/$(MODULE) 51 | 52 | docs: $(DOC_FILE) 53 | 54 | $(DOC_FILE): $(DOC_SOURCES) 55 | find . -type f \( -name '*.lua' -o -name '*.m' \) -not -name 'template.*' -not -path './_*' -exec cat {} + | __doc_tools/gencomments | __doc_tools/genjson > $@ 56 | 57 | install-docs: docs 58 | mkdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE) 59 | install -m 0644 $(DOC_FILE) $(PREFIX)/hs/_asm/undocumented/$(MODULE) 60 | 61 | clean: 62 | rm -v -rf $(SOFILE) *.dSYM $(DOC_FILE) 63 | 64 | uninstall: 65 | rm -v -f $(PREFIX)/hs/_asm/undocumented/$(MODULE)/{$(subst $(space),$(comma),$(ALLFILES))} 66 | (pushd $(PREFIX)/hs/_asm/undocumented/$(MODULE)/ ; rm -v -fr $(OBJCFILE:.m=.so.dSYM) ; popd) 67 | rm -v -f $(PREFIX)/hs/_asm/undocumented/$(MODULE)/$(DOC_FILE) 68 | rmdir -p $(PREFIX)/hs/_asm/undocumented/$(MODULE) ; exit 0 69 | 70 | .PHONY: all clean uninstall verify docs install install-objc install-lua install-docs 71 | -------------------------------------------------------------------------------- /cursor/init.lua: -------------------------------------------------------------------------------- 1 | --- === hs._asm.module === 2 | --- 3 | --- Functions for module 4 | --- 5 | --- A description of module. 6 | 7 | 8 | local module = require("hs._asm.undocumented.cursor.internal") 9 | 10 | -- private variables and methods ----------------------------------------- 11 | 12 | -- Public interface ------------------------------------------------------ 13 | 14 | -- Return Module Object -------------------------------------------------- 15 | 16 | return module 17 | -------------------------------------------------------------------------------- /cursor/internal.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "CGSCursor.h" 4 | 5 | extern CGSConnectionID _CGSDefaultConnection(void) ; 6 | #define CGSDefaultConnection _CGSDefaultConnection() 7 | 8 | // #define USERDATA_TAG "hs.module" 9 | int refTable ; 10 | 11 | // #define get_objectFromUserdata(objType, L, idx) (objType*)*((void**)luaL_checkudata(L, idx, USERDATA_TAG)) 12 | // #define get_structFromUserdata(objType, L, idx) ((objType *)luaL_checkudata(L, idx, USERDATA_TAG)) 13 | 14 | static int showCursor(lua_State *L) { 15 | [[LuaSkin shared] checkArgs:LS_TBREAK] ; 16 | CGError state = CGSShowCursor(CGSDefaultConnection) ; 17 | if (state != kCGErrorSuccess) return luaL_error(L, "showCursor:error %d", state) ; 18 | return 0 ; 19 | } 20 | 21 | static int hideCursor(lua_State *L) { 22 | [[LuaSkin shared] checkArgs:LS_TBREAK] ; 23 | CGError state = CGSHideCursor(CGSDefaultConnection) ; 24 | if (state != kCGErrorSuccess) return luaL_error(L, "hideCursor:error %d", state) ; 25 | return 0 ; 26 | } 27 | 28 | static int obscureCursor(lua_State *L) { 29 | [[LuaSkin shared] checkArgs:LS_TBREAK] ; 30 | CGError state = CGSObscureCursor(CGSDefaultConnection) ; 31 | if (state != kCGErrorSuccess) return luaL_error(L, "obscureCursor:error %d", state) ; 32 | return 0 ; 33 | } 34 | 35 | static int revealCursor(lua_State *L) { 36 | [[LuaSkin shared] checkArgs:LS_TBREAK] ; 37 | CGError state = CGSRevealCursor(CGSDefaultConnection) ; 38 | if (state != kCGErrorSuccess) return luaL_error(L, "revealCursor:error %d", state) ; 39 | return 0 ; 40 | } 41 | 42 | static int waitCursor(lua_State *L) { 43 | [[LuaSkin shared] checkArgs:LS_TBOOLEAN, LS_TBREAK] ; 44 | CGError state = CGSForceWaitCursorActive(CGSDefaultConnection, lua_toboolean(L, 1)) ; 45 | if (state != kCGErrorSuccess) return luaL_error(L, "waitCursor:error %d", state) ; 46 | return 0 ; 47 | } 48 | 49 | static int cursorSeed(lua_State *L) { 50 | [[LuaSkin shared] checkArgs:LS_TBREAK] ; 51 | lua_pushinteger(L, CGSCurrentCursorSeed()) ; 52 | return 1 ; 53 | } 54 | 55 | static int systemCursorName(lua_State *L) { 56 | [[LuaSkin shared] checkArgs:LS_TNUMBER, LS_TBREAK] ; 57 | lua_pushstring(L, CGSCursorNameForSystemCursor(luaL_checkinteger(L, 1))) ; 58 | return 1 ; 59 | } 60 | 61 | static int cursorScale(lua_State *L) { 62 | [[LuaSkin shared] checkArgs:LS_TNUMBER | LS_TOPTIONAL, LS_TBREAK] ; 63 | if (lua_type(L, 1) == LUA_TNUMBER) { 64 | CGError state = CGSSetCursorScale(CGSDefaultConnection, lua_tonumber(L, 1)) ; 65 | if (state != kCGErrorSuccess) return luaL_error(L, "cursorScale:set error %d", state) ; 66 | } 67 | CGFloat scale ; 68 | CGError state = CGSGetCursorScale(CGSDefaultConnection, &scale) ; 69 | if (state != kCGErrorSuccess) return luaL_error(L, "cursorScale:get error %d", state) ; 70 | lua_pushnumber(L, scale) ; 71 | return 1 ; 72 | } 73 | 74 | static int pushSystemCursorTable(lua_State *L) { 75 | lua_newtable(L) ; 76 | lua_pushinteger(L, CGSCursorArrow) ; lua_setfield(L, -2, "arrow") ; 77 | lua_pushinteger(L, CGSCursorIBeam) ; lua_setfield(L, -2, "iBeam") ; 78 | lua_pushinteger(L, CGSCursorIBeamXOR) ; lua_setfield(L, -2, "iBeamXOR") ; 79 | lua_pushinteger(L, CGSCursorAlias) ; lua_setfield(L, -2, "alias") ; 80 | lua_pushinteger(L, CGSCursorCopy) ; lua_setfield(L, -2, "copy") ; 81 | lua_pushinteger(L, CGSCursorMove) ; lua_setfield(L, -2, "move") ; 82 | lua_pushinteger(L, CGSCursorArrowContext) ; lua_setfield(L, -2, "arrowContext") ; 83 | lua_pushinteger(L, CGSCursorWait) ; lua_setfield(L, -2, "wait") ; 84 | lua_pushinteger(L, CGSCursorEmpty) ; lua_setfield(L, -2, "empty") ; 85 | return 1 ; 86 | } 87 | 88 | // static int userdata_tostring(lua_State* L) { 89 | // } 90 | 91 | // static int userdata_eq(lua_State* L) { 92 | // } 93 | 94 | // static int userdata_gc(lua_State* L) { 95 | // return 0 ; 96 | // } 97 | 98 | // static int meta_gc(lua_State* __unused L) { 99 | // return 0 ; 100 | // } 101 | 102 | // Metatable for userdata objects 103 | // static const luaL_Reg userdata_metaLib[] = { 104 | // {"__tostring", userdata_tostring}, 105 | // {"__eq", userdata_eq}, 106 | // {"__gc", userdata_gc}, 107 | // {NULL, NULL} 108 | // }; 109 | 110 | // Functions for returned object when module loads 111 | static luaL_Reg moduleLib[] = { 112 | {"showCursor", showCursor}, 113 | {"hideCursor", hideCursor}, 114 | {"obscureCursor", obscureCursor}, 115 | {"revealCursor", revealCursor}, 116 | {"waitCursor", waitCursor}, 117 | {"cursorSeed", cursorSeed}, 118 | {"systemCursorName", systemCursorName}, 119 | {"cursorScale", cursorScale}, 120 | 121 | {NULL, NULL} 122 | }; 123 | 124 | // // Metatable for module, if needed 125 | // static const luaL_Reg module_metaLib[] = { 126 | // {"__gc", meta_gc}, 127 | // {NULL, NULL} 128 | // }; 129 | 130 | // NOTE: ** Make sure to change luaopen_..._internal ** 131 | int luaopen_hs__asm_undocumented_cursor_internal(lua_State* __unused L) { 132 | // Use this if your module doesn't have a module specific object that it returns. 133 | refTable = [[LuaSkin shared] registerLibrary:moduleLib metaFunctions:nil] ; // or module_metaLib 134 | // Use this some of your functions return or act on a specific object unique to this module 135 | // refTable = [[LuaSkin shared] registerLibraryWithObject:USERDATA_TAG 136 | // functions:moduleLib 137 | // metaFunctions:nil // or module_metaLib 138 | // objectFunctions:userdata_metaLib]; 139 | 140 | pushSystemCursorTable(L) ; lua_setfield(L, -2, "systemCursors") ; 141 | return 1; 142 | } 143 | --------------------------------------------------------------------------------