Release: 26.2.2022
- New app icon by Parakeet (#286)!
- Improved documentation! 👩🏼💻 The documentation is now powered by Docusaurus and hosted at https://kasper.github.io/phoenix/.
- Add support for an input modal 🚀 (#163).
- Add support to customise text alignment, font and colour in modals (#158, #242).
- Add support for device sleep events (#282).
- Add support for moving windows to spaces in macOS 12.0 with
Space#moveWindows(...)
(#289).
- Breaking: Phoenix now requires OS X El Capitan (10.11) or higher.
- Breaking: “Open at Login” is now using a launcher app instead of adding Phoenix to the deprecated login items of your user account. This setting will not be reflected anymore in the list and you can remove the app from it. You may need to enable this setting again for Phoenix to launch automatically after this update, depending on how you setup it the first time.
- Upgrade Sparkle to 2.1.0.
- Add support for Xcode 13.1 by properly importing the “Application Services” framework for Accessibility APIs (#285).
- Reload configuration automatically when “Accessibility” permission changes.
- Show more details about raised exception in the notification message.
- Close open modals when configuration is reloaded.
- Fix crash if
Space#addWindows
orSpace#removeWindows
are passed an object that is not an instance of a Window. - Fix issue that could cause the status bar item to be rendered multiple times when reloading the configuration.
- New: Event
deviceWillSleep
is triggered when the device will sleep (#282). - New: Event
deviceDidWake
is triggered when the device did wake (#282).
- New: Property
hasShadow
for whether the modal has a shadow. - New: Property
textAlignment
for the alignment of the text (#158). - New: Property
font
for the font name used for the text (#158). - New: Property
isInput
for whether the modal behaves as an input modal (#163). - New: Property
inputPlaceholder
for the placeholder string that will be displayed when the input is empty (#163). - New: Property
textDidChange
callback function to call when the input modal’s text field value changes (#163). - New: Function
setTextColour(...)
orsetTextColor(...)
sets a custom text colour with the given RGBA values (#158, #242).
- New: Function
moveWindows(...)
moves the given windows to the space (macOS 10.13+) (#289).
Release: 24.10.2021
- Forward
console.log(...)
toPhoenix.log(...)
for convenience. - Log stack trace when passing an error to
Phoenix.log(...)
(#181). - Upgrade Sparkle to 1.27.0.
- Xcode 13 is now required for building.
- Launch Console app when clicking a notification for an exception.
- Clarify the documentation about
Point
,Size
andRectangle
being simple struct objects and not being extendable (#273).
Release: 21.3.2021
- Upgrade Sparkle to 1.26.0.
- Fix issue that prevented window events to register for recently launched apps (#264).
- Fix issue that caused
App#mainWindow()
to return a broken Window instance when the app is for example minimised. The function will now correctly returnundefined
in such cases (#269).
Release: 24.1.2021
- Add temporary workaround for macOS bug that breaks focusing an individual window of an app in Big Sur (#266, #268).
Release: 29.11.2020
- Add support for Apple Silicon.
- Improve first launch experience by removing custom alert before accessibility prompt and terminating Phoenix.
- Improve debug capabilities in Safari Web Inspector by listing configuration file sources (#265).
- Upgrade Sparkle to 1.24.0.
- Xcode 12 is now required for building.
Release: 14.6.2020
- Upgrade Sparkle to 1.23.0.
- Fix issue that caused Phoenix to crash when binding keys with some keyboard layouts (#196).
Release: 24.1.2020
- Add support to load images from files which can be used as custom icons in modals (#226).
- Notarise Phoenix with Apple to pass Gatekeeper verification (#241).
- Upgrade Lodash to 4.17.15 (from 4.17.5).
- Upgrade Sparkle to 1.22.0.
- Remove Grunt and use standard scripts to build library.
- Xcode 11 is now required for building.
- Fix an issue that caused a crash if accessing screens for a space under some circumstances (#231).
- New: Add support for
command
,option
andcontrol
as additional key modifiers. This is purely syntactic sugar representing newer Apple keyboard layouts and they alias the existingcmd
,alt
andctrl
modifiers in this order (#173).
- New: Function
fromFile(String path)
loads an image from the given path, the path is resolved before attempting to load the image, returnsundefined
if unsuccessful (#226).
Release: 7.6.2018
- Upgrade Lodash to 4.17.5 (from 4.17.4).
- Upgrade Sparkle to 1.19.0.
- New: Property
animationDuration
defines the animation duration (in seconds) for showing and closing the modal, if the duration is set to0
the animation will be disabled, by default0.2
(#203).
- Change: Function
launch(...)
now supports a focus option to focus the app automatically on launch (#211, #212).
Release: 8.4.2018
- Add support for one-time managed handlers for both keys and events (#201).
- New: Function
once(String key, Array<String> modifiers, Function callback)
constructs a managed handler for a key that is by default only triggered one time and then disabled, for more control you can explicitly returnfalse
from the callback function and the handler will not be disabled until you return something else, for arguments seenew Key(...)
(#201).
- New: Function
once(String event, Function callback)
constructs a managed handler for an event that is by default only triggered one time and then disabled, for more control you can explicitly returnfalse
from the callback function and the handler will not be disabled until you return something else, for arguments seenew Event(...)
(#201).
Release: 25.12.2017
- Add support for closing windows (#184).
- Upgrade Sparkle to 1.18.1.
- Xcode 9 is now required for building.
- Improve documentation for the behaviour of
Window#raise()
(#164).
- Fix an issue where
PHShebangPreprocessor
blocks due to a race condition (reference, #167, #169). - Fix an issue that removed Phoenix from the login items on reload when preference was set through the status bar menu (#194).
- New: Function
close()
closes the window, returnstrue
if successful (#184).
Release: 22.1.2017
- If you did not already know, macOS Sierra (10.12) has full support for the ECMAScript 6 standard and you can now use it with Phoenix! Read a quick overview of the new features added to the language.
- Add support for getting the topmost window at a specified point (#149).
- Add “Edit configuration” status menu item (#156).
- Add support for mouse drag events (#159).
- Lodash is upgraded to 4.17.4 (from 4.17.3).
- New: Event
mouseDidLeftDrag
is triggered when the mouse did left drag (#159). - New: Event
mouseDidRightDrag
is triggered when the mouse did right drag (#159).
- New: Function
at(Point point)
returns the topmost window at the specified point, can beundefined
if no window is present at the given position (#149).
Release: 26.12.2016
- Breaking: Underscore.js is replaced with Lodash (4.17.3) (#89).
- Xcode 8 is now required for building.
- Fix an issue that caused inconsistencies with screens and spaces when “Displays have separate Spaces” option was disabled in macOS (#130).
- Fix an issue that prevented Phoenix from terminating after accessibility prompt (#132).
- Fix an issue that prevented preferences to be observed on launch (#133).
- Fix an issue that prevented task callbacks from performing actions on the main thread (#137).
- Change: Function
log(...)
now supports multiple arguments (#157).
- Change: Function
run(String path, Array arguments, Function callback)
can now be called without a callback (#135).
- New: Function
screens()
returns all screens to which the space belongs to (#130). - Deprecation: Function
screen()
is deprecated and will be removed in later versions, usescreens()
instead (#130).
- New: Function
raise()
raises the window so it will be beneath the focused window, returnstrue
if successful (#151).
Release: 6.8.2016
- Modals have a new improved “vibrant” appearance and can now display icons as well as text. All the new options are described in the API (#126).
- Callback for key is now called repeatedly when key is held down (#119).
- Improvements on exception handling. When present, the line and column number are also logged for exceptions.
- Performance improvements.
- Fix issue that prevented
Window#setFrame(...)
to only set the origin for windows that cannot be resized (#124).
- Change: All mouse events receive the corresponding
Point
-object as the first argument for the callback function (#125).
- Change: The callback function receives its handler as the first argument and as the second argument a boolean that indicates if the key was repeated (held down) (#119).
- New: Function
build(Map<String, AnyObject> properties)
builds a modal with the specified properties and returns it,origin
should be a function that receives the frame for the modal as the only argument and returns aPoint
-object will be set as the origin for the modal (#126). - New: Dynamic property
weight
defines the weight of the modal (in points), by default24
(#126). - New: Property
appearance
defines the appearance of the modal (dark|light|transparent
), by defaultdark
(#126). - New: Dynamic property
icon
defines the icon displayed in the modal (#126). - New: Dynamic property
text
defines the text displayed in the modal (#126). - Change: Origin is now a dynamic property (#126).
- Deprecation: Property
message
is deprecated and will be removed in later versions, usetext
instead (#126).
- New: Function
frame()
returns the whole frame for the screen, bottom-left based origin (#128). - New: Function
visibleFrame()
returns the visible frame for the screen subtracting the Dock and Menu from the frame when visible, bottom-left based origin (#128). - New: Function
currentSpace()
returns the current space for the screen (macOS 10.11+, returnsundefined
otherwise) (#120). - Change: Function
frameInRectangle()
is nowflippedFrame()
(#128). - Change: Function
visibleFrameInRectangle()
is nowflippedVisibleFrame()
(#128). - Deprecation: Function
frameInRectangle()
is deprecated and will be removed in later versions, useflippedFrame()
instead (#128). - Deprecation: Function
visibleFrameInRectangle()
is deprecated and will be removed in later versions, useflippedVisibleFrame()
instead (#128).
- New: Function
icon()
returns the icon for the app (#126).
Release: 13.7.2016
- Fix issue that prevented
Window#others(...)
returning the correct windows based on the screen optional (#116). - Fix crash when trying to traverse spaces (#117).
Release: 12.7.2016
- Adds support for mouse events (#90).
- Phoenix now has a key–value storage that can be used to store values across reloads and reboots as JSON, see Storage (#97).
- You can now run tasks asynchronously and retrieve their status, standard output and standard error. A new
Task
-object has been created to construct tasks, access their properties or to terminate the task, see its API (#98). - Keys, events and timers are now constructed with relevant constructors instead of creating them through the global
Phoenix
-object (#109). - Add support for British alternatives to the API (#113).
- Breaking: Global
Command
-object has been removed, useTask
instead as a direct replacement (#98). - Breaking: You can now have multiple
Key
s for a single key combination. However, only one can be enabled at a time. Previously binding would only change the callback for an existing handler if a previously bound key combination was used again. Now, binding a key combination will always return a new unique handler. As before, this new handler is always enabled by default. Subsequently, any previous handler for the key combination will therefor be automatically disabled (#99). - Breaking: Name and stylistic changes to the API (#108).
- Breaking:
KeyHandler
has been renamed toKey
,EventHandler
toEvent
andTimerHandler
toTimer
(#109). - Debug configuration file suffix has changed from
-debug.js
to.debug.js
.
- New: Event
willTerminate
is triggered when Phoenix will terminate, use this event to perform any tasks before the application terminates. - New: Event
mouseDidMove
is triggered when the mouse has moved (#90). - New: Event
mouseDidLeftClick
is triggered when the mouse did left click (#90). - New: Event
mouseDidRightClick
is triggered when the mouse did right click (#90). - Change: Event
start
is nowdidLaunch
.
- Deprecation: Function
bind(String key, Array<String> modifiers, Function callback)
has been removed, use constructornew Key(String key, Array<String> modifiers, Function callback)
instead (#109). - Deprecation: Function
on(String event, Function callback)
has been removed, use constructornew Event(String event, Function callback)
instead (#109). - Deprecation: Function
after(double interval, Function callback)
has been removed, use constructornew Timer(double interval, boolean repeats, Function callback)
instead (#109). - Deprecation: Function
every(double interval, Function callback)
has been removed, use constructornew Timer(double interval, boolean repeats, Function callback)
instead (#109).
- Change: Function
enable()
will disable any previous handler for the same key combination automatically (#99).
- New: Function
disable()
disables the event handler.
- Change: Function
mainScreen()
is now simplymain()
(#108). - Change: Function
screens()
is nowall()
(#108). - Change: Function
windows()
now takes optionalswindows(Map<String, AnyObject> optionals)
(#108). - Deprecation: Function
visibleWindows()
has been removed, usewindows({ visible: true })
instead (#108).
- Change: Function
activeSpace()
is now simplyactive()
(#108). - Change: Function
spaces()
is nowall()
(#108). - Change: Function
windows()
now takes optionalswindows(Map<String, AnyObject> optionals)
(#108). - Deprecation: Function
visibleWindows()
has been removed, usewindows({ visible: true })
instead (#108).
- Change: Function
moveTo()
is now simplymove()
(#108).
- Change: Function
focusedApp()
is now simplyfocused()
(#108). - Change: Function
runningApps()
is nowall()
(#108). - Change: Function
windows()
now takes optionalswindows(Map<String, AnyObject> optionals)
(#108). - Change: Function
terminate()
now takes optionalsterminate(Map<String, AnyObject> optionals)
(#108). - Deprecation: Function
visibleWindows()
has been removed, usewindows({ visible: true })
instead (#108). - Deprecation: Function
forceTerminate()
has been removed, useterminate({ force: true })
instead (#108).
- New: Function
neighbours(String direction)
returns windows to the direction (west|east|north|south
) of the window (#108). - New: Function
focusClosestNeighbour(String direction)
focuses the closest window to the direction (west|east|north|south
) of the window, returnstrue
if successful (#108). - Change: Function
focusedWindow()
is now simplyfocused()
(#108). - Change: Function
windows()
is nowall(Map<String, AnyObject> optionals)
(#108). - Change: Function
visibleWindowsInOrder()
is nowrecent()
(#108). - Change: Function
otherWindowsOnAllScreens()
is nowothers(Map<String, AnyObject> optionals)
(#108). - Deprecation: Function
visibleWindows()
has been removed, useall({ visible: true })
instead (#108). - Deprecation: Function
otherWindowsOnSameScreen()
has been removed, useothers({ screen: window.screen() })
instead (#108). - Deprecation: Functions
windowsToWest()
,windowsToEast()
,windowsToNorth()
andwindowsToSouth()
have been removed, use insteadneighbours('west')
,neighbours('east')
,neighbours('north')
andneighbours('south')
respectively (#108). - Deprecation: Functions
focusClosestWindowInWest()
,focusClosestWindowInEast()
,focusClosestWindowInNorth()
andfocusClosestWindowInSouth()
have been removed, use insteadfocusClosestNeighbour('west')
,focusClosestNeighbour('east')
,focusClosestNeighbour('north')
andfocusClosestNeighbour('south')
respectively (#108).
Release: 27.6.2016
- Phoenix can now manage handlers for you. Instead of
Phoenix.bind
,Phoenix.on
,Phoenix.after
orPhoenix.every
— useKey.on
,Event.on
,Timer.after
andTimer.every
. For more, see the API (#107).
- Implement
setTimeout
,setInterval
,clearTimeout
andclearInterval
. This also adds support for timing related functions from Underscore (#92). - Make require throw an error if a file cannot be resolved (#93).
- Add support for ISO section
§
-key (#102).
- Disable key handlers immediately to ensure that keys are unregistered before setting up a new context (#94).
- Fix crash caused by moving or deleting configuration directory while app is running (#105).
Release: 29.4.2016
- Notify when preprocessing failed.
- Fix an issue that prevented preprocessing due to incompatible paths between different shells (#88).
Release: 25.4.2016
- Phoenix now supports Spaces! These features are only supported on El Capitan (10.11) and upwards. A new global
Space
-object has been created to control spaces, see the API (#60). - Preferences can now be set programmatically through the API (#67).
- Phoenix can be run completely in the background, this also removes the status bar menu, see the
daemon
-preference in the API (#68). - You can now create timers to achieve delays and timed events. A new
TimerHandler
-object has been created to control timers, see its API. See the functionsPhoenix.after(double interval, Function callback)
andPhoenix.every(double interval, Function callback)
in the API to create timers (#77).
- Upgrade Sparkle to 1.14.0. This also fixes the HTTP MITM-vulnerability discovered in Sparkle — though Phoenix was never vulnerable since we use HTTPS to secure updates.
- Adjust latency of context reloads on configuration file changes to limit race conditions (#83).
- Objects that implement
Iterable
can be traversed. Namely,Screen
andSpace
. - All handlers now receive their handlers as the last argument for the callback function.
- Improvements to memory management and other small improvements.
- Improve error handling in preprocessing (#65).
- Fix an issue that prevented an exception raised in a handler callback to be caught and reported (#70).
- Fix an issue that prevented setting the frame for a window correctly while moving it to a smaller screen (#84).
- New: Event
spaceDidChange
is triggered when the active space has changed.
- New: Function
after(double interval, Function callback)
creates a timer that fires the callback once after the given interval (in seconds) and returns the handler, you must keep a reference to the handler in order for your callback to get called, the callback function receives its handler as the only argument. - New: Function
every(double interval, Function callback)
creates a timer that fires the callback repeatedly until stopped using the given interval (in seconds) and returns the handler, you must keep a reference to the handler in order for your callback to get called, the callback function receives its handler as the only argument. - New: Function
set(Map<String, AnyObject> preferences)
sets the preferences from the given key–value map, any previously set preferences with the same key will be overridden. - Change: The callback for function
bind(String key, Array<String> modifiers, Function callback)
now receives its handler as the only argument, previously the callback received no arguments. - Change: The callback for function
on(String event, Function callback)
now receives its handler as the last argument.
- New: Function
identifier()
returns the UUID for the screen (#79). - New: Function
spaces()
returns all spaces for the screen (OS X 10.11+, returns an empty list otherwise).
- New: Function
isFullScreen()
returnstrue
if the window is a full screen window (#60, #80). - New: Function
spaces()
returns the spaces where the window is currently present (OS X 10.11+, returns an empty list otherwise). - New: Function
setFullScreen(boolean value)
sets whether the window is full screen (#60, #80).
Release: 12.12.2015
- Amend license regarding the Phoenix icon assets contributed by Jason Milkins for not being under the MIT License (#61).
- Fix issue where
Mouse.location()
andMouse.moveTo(Point point)
used different coordinate origins. Both now correctly use top-left as the origin (#58). - Support shells (e.g. Fish) that do not support
-cl
option shorthand in preprocessing (#57).
Release: 28.11.2015
- Phoenix now supports events! See the API. To bind an event to a callback function, you call the
on
-function for thePhoenix
-object. - You may now use JavaScript preprocessing and languages such as CoffeeScript to write your Phoenix-configuration (#45). Thanks @shayne!
- Updates are now delivered and installed through Sparkle (#50).
- Phoenix now supports additional configuration locations. In addition to
~/.phoenix.js
, you may also use~/Library/Application Support/Phoenix/phoenix.js
or~/.config/phoenix/phoenix.js
if you prefer to do so (#52).
- Phoenix has been rewritten and refactored from the ground up. This also means that Phoenix now requires OS X Yosemite (10.10) or higher. Xcode 7 is now required for building.
- Supports OS X El Capitan (10.11).
- Underscore.js is upgraded to 1.8.3 (from 1.5.2). This may change existing behaviour related to Underscore.
- Global
api
-object is now calledPhoenix
. - Global
MousePosition
-object is now calledMouse
. Hotkey
-object is now calledKeyHandler
and its properties have changed. See the API.- The concept of
Alerts
has been deprecated. A new globalModal
-object has been created to display messages as modals. See the API. - A new
EventHandler
-object has been created to handle events. See the API. - A new global
Command
-object has been created to run UNIX-commands. See the API.
- A new subtler status item icon.
- Alerts are now delivered through Notification Center and logged to Console for easier debugging.
- Now reloading the context gives no alert unless an error is encountered.
- Objects that implement
Identifiable
can be identified and compared.
- Support non-unicode keyboards (#34).
- Support relative requires with symlinks in configuration (#42).
- New: Function
on(String event, Function callback)
binds an event to a callback function. - New: Function
notify(String message)
delivers a message to the Notification Center. - Change: Function
launch(String appName)
has moved to the globalApp
-object. - Change: Function
runCommand(String commandPath, Array arguments)
has moved to a new globalCommand
-object and is now calledrun(String path, Array arguments)
. - Deprecation: Function
alert(String message, double durationInSeconds)
has been removed, useModal
to display messages as modals. - Deprecation: Function
cancelAlerts()
has been removed, you must keep references to modals yourself to close them. - Deprecation: Function
setTint(Array<double> red, Array<double> green, Array<double> blue)
has been removed with no replacement.
- New: KeyHandler now implements
Identifiable
. - Change: You must now keep a reference to the handler, otherwise your callback will not get called.
- Change: Special keys are now camelCased (case sensitive) instead of underscored. See changed keys.
- Change: Keys for keypad are now prefix with
keypad
instead ofpad
.
- New: Screen now implements
Identifiable
. - New: Function
mainScreen()
returns the screen containing the window with the keyboard focus. - New: Function
screens()
returns all screens. - New: Function
windows()
returns all windows for the screen. - New: Function
visibleWindows()
returns all visible windows for the screen. - Change: For clarity, functions
frameIncludingDockAndMenu()
andframeWithoutDockOrMenu()
are nowframeInRectangle()
andvisibleFrameInRectangle()
, respectively. - Change: Functions
nextScreen()
andpreviousScreen()
are now simplynext()
andprevious()
.
- New: Function
moveTo(Point point)
returns a boolean value for determining success. - Change: Functions
capture()
andrestore(Point point)
are now calledlocation()
andmoveTo(Point point)
.
- New: App now implements
Identifiable
. - New: All actions return a boolean value for determining success.
- New: Function
get(String appName)
returns the running app with the given name. - New: Function
launch(String appName)
now returns the launched app if successful. - New: Function
focusedApp()
returns the focused app. - New: Function
isActive()
returns whether the app is currently frontmost. - New: Function
isTerminated()
returns whether the app has been terminated. - New: Function
mainWindow()
returns the main window for the app. - New: A new function
focus()
focuses the app and its windows. - Change: Property
pid
is now a function calledprocessIdentifier()
. - Change: Function
title()
is now calledname()
. - Change: Function
allWindows()
is now simplywindows()
. - Change: Functions
kill()
andkill9()
are nowterminate()
andforceTerminate()
, respectively.
- New: Window now implements
Identifiable
. - New: All actions return a boolean value for determining success.
- New: Function
isMain()
returns whether the window is the main window for its app. - New: Function
isVisible()
returns whether the window is a normal and unminimised window that belongs to an unhidden app. - Change: Function
allWindows()
is now simplywindows()
. - Change: Function
visibleWindowsMostRecentFirst()
is renamed tovisibleWindowsInOrder()
for clarity. - Change: Function
isNormalWindow()
is now simplyisNormal()
. - Change: Function
isWindowMinimized()
is now simplyisMinimized()
. - Change: Function
unMinimize()
is nowunminimize()
. - Change: Function
focusWindow()
is nowfocus()
. - Change: Alignment functions
windowsToWest(), windowsToEast(), windowsToNorth(), windowsToSouth()
now correctly return windows relative to the window and not relative to the focused window. To achieve the previous behaviour you need chain these with thefocusedWindow()
-accessor. This also affectsfocusClosestWindowInWest(), focusClosestWindowInEast(), focusClosestWindowInNorth(), focusClosestWindowInSouth()
-functions. - Change: Functions
focusWindowLeft(), focusWindowRight(), focusWindowUp(), focusWindowDown()
are nowfocusClosestWindowInWest(), focusClosestWindowInEast(), focusClosestWindowInNorth(), focusClosestWindowInSouth()
, respectively.