Created
February 20, 2020 17:16
-
-
Save spacelatte/c2e847381bf1654821b25cd8e5ee571a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/* | |
window (right-hand) | |
kbd-focused | |
under-mouse | |
screen (left-hand) | |
kbd-focus | |
under-mouse | |
*/ | |
const showDebugModals = false | |
let lastSpaceChangeTime = Date.now() | |
let lastMouseMoveTime = Date.now() | |
let lastClickTimes = [ 0, 0, 0, ].map(function(i) { return Date.now() }) | |
let lastDragTimes = [ 0, 0, 0, ].map(function(i) { return Date.now() }) | |
Phoenix.set({ | |
daemon: false, | |
openAtLogin: true, | |
}) | |
let mod = [ 'ctrl', 'alt', 'shift', 'cmd' ] | |
let keyHandlers = [] | |
function frameToFlipped(frame) { | |
return { | |
...frame, | |
y: Screen.all()[0].frame().height - frame.y, | |
} | |
} | |
function frameCenterOf(frame) { | |
return { | |
...frame, | |
x: frame.x + frame.width / 2, | |
y: frame.y + frame.height / 2, | |
} | |
} | |
function frameCenterOfCenteringOther(parent, inner) { | |
return { | |
...parent, | |
x: parent.x - inner.width / 2, | |
y: parent.y - inner.height / 2, | |
} | |
} | |
function modalMaker(text, position=null, opts) { | |
if(!showDebugModals) return | |
let options = opts || {} | |
return Modal.build({ | |
animationDuration: 0.15, | |
duration: 1.0, | |
weight: 16, | |
...options, | |
text: text, | |
origin: function(frame) { | |
switch(true) { | |
case (position === null || position === undefined): | |
return frameCenterOfCenteringOther( | |
frameCenterOf(Screen.main().flippedFrame()), | |
frame, | |
) | |
case (typeof(position) === "function"): | |
return position(frame) | |
case (typeof(position) === "object"): | |
return position | |
case (typeof(position) === "list"): | |
return { x: position[0], y: position[1], } | |
} | |
return { | |
x: 0, | |
y: 0, | |
} | |
}, | |
}).show() | |
} | |
function screenGetIndexAtPointerPosition() { | |
let location = Mouse.location() | |
return Screen.all().map(function(screen, index) { | |
let frame = screen.flippedFrame() | |
return ( | |
(frame.x < location.x && location.x < (frame.x + frame.width)) | |
&& | |
(frame.y < location.y && location.y < (frame.x + frame.height)) | |
) | |
}).indexOf(true) | |
} | |
function screenPointRelativeToRightOfFrame(frame, offset) { | |
return { | |
x: frame.x + frame.width - ( | |
typeof(offset) === "object" && "x" in offset | |
? offset.x | |
: offset | |
), | |
y: frame.y, | |
} | |
} | |
function screenOfOffsetRelativeToPointerPosition(index, direction) { | |
let screens = Screen.all() | |
return screens[(index+direction+screens.length)%screens.length] | |
} | |
function shouldMovePassiveMouseToCenterOfFrame(frame, clickIgnoreDelay=333) { | |
let now = Date.now() | |
if(Math.abs(now - lastMouseMoveTime) < clickIgnoreDelay) | |
return | |
if(Math.abs(now - lastSpaceChangeTime) < clickIgnoreDelay) | |
return | |
let filterCallback = function(item) { | |
let diff = Math.abs(now - item) | |
return (diff < clickIgnoreDelay) | |
} | |
let lastClicks = lastClickTimes.filter(filterCallback) | |
let lastDrags = lastDragTimes.filter(filterCallback) | |
if(0 === lastClicks.length && 0 === lastDrags.length) { | |
//if(Math.abs(now - lastMouseMoveTime) > clickIgnoreDelay) | |
Mouse.move(frameCenterOf(frame)) | |
} | |
return | |
} | |
function screenMouseMoveRelative(direction) { | |
let indexOfScreen = screenGetIndexAtPointerPosition() | |
let destScreen = screenOfOffsetRelativeToPointerPosition( | |
indexOfScreen, | |
direction, | |
) | |
modalMaker("[ here ]", function(frame) { | |
return frameCenterOfCenteringOther( | |
frameCenterOf(destScreen.frame()), | |
frame, | |
) | |
}) | |
Mouse.move(frameCenterOf(destScreen.flippedFrame())) | |
return | |
} | |
function screenMoveActiveWindowRelative(direction, withMouse=false) { | |
let indexOfScreen = screenGetIndexAtPointerPosition() | |
let destScreen = screenOfOffsetRelativeToPointerPosition( | |
indexOfScreen, | |
direction, | |
) | |
let window = Window.at(Mouse.location()) | |
if(window) { | |
let targetFrame = frameCenterOf(destScreen.flippedFrame()) | |
window.setTopLeft(frameCenterOfCenteringOther(targetFrame, window.frame())) | |
if(withMouse) Mouse.move(targetFrame) | |
} | |
return | |
} | |
// window focusing helpers | |
function windowFocusQuickMoveByPointer(direction) { | |
let window = Window.at(Mouse.location()) | |
//if(window) window.focusClosestNeighbour(direction) | |
windowDisplayNeighboursInDirection(window, direction) | |
return | |
} | |
function windowFocusQuickMoveByWindow(direction) { | |
let window = Window.focused() | |
//if(window) window.focusClosestNeighbour(direction) | |
windowDisplayNeighboursInDirection(window, direction) | |
return | |
} | |
keyHandlers.push(Key.on('z', mod, function () { | |
let screen = Screen.main().flippedVisibleFrame() | |
let window = Window.focused() | |
if(!window) return | |
window.setTopLeft({ | |
x: screen.x + (screen.width / 2) - (window.frame().width / 2), | |
y: screen.y + (screen.height / 2) - (window.frame().height / 2), | |
}) | |
return | |
})) | |
//Window.focused().setTopLeft({ x: 0, y: 0 }); | |
//debugger; | |
//require("./Library/Application Support/Phoenix/purag.meat.phoenix.js") | |
// Phoenix | |
Event.on("didLaunch", function() { | |
console.log(arguments) | |
}) | |
Event.on("willTerminate", function() { | |
console.log(arguments) | |
}) | |
// Screen & Space | |
Event.on("screensDidChange", function() { | |
return console.log("screensDidChange", arguments) | |
}) | |
Event.on("spaceDidChange", function(event) { | |
lastSpaceChangeTime = Date.now() | |
let self = Space.active() | |
if(!self) return | |
self.screens().forEach(function(screen, index) { | |
modalMaker( | |
JSON.stringify({ | |
normal: self.isNormal(), | |
fullScreen: self.isFullScreen(), | |
screens: self.screens().length, | |
windows: self.windows().length, | |
}, null, 4), | |
function(frame) { | |
return frameCenterOfCenteringOther( | |
frameCenterOf(screen.frame()), | |
frame, | |
) | |
}, | |
{ | |
duration: 1.0, | |
weight: 16, | |
}, | |
) | |
}) | |
return console.log("spaceDidChange", event) | |
}) | |
// App | |
Event.on("appDidLaunch", function(app) { | |
return console.log("appDidLaunch", app) | |
}) | |
Event.on("appDidTerminate", function(app) { | |
return console.log("appDidTerminate", app) | |
}) | |
Event.on("appDidActivate", function(app, event) { | |
let self = app || App.focused() | |
if(!self) return | |
let window = self.mainWindow() | |
if(window) Timer.after(0.1, function() { | |
return shouldMovePassiveMouseToCenterOfFrame(window.frame()) | |
}) | |
let text = `App/Activate: ${JSON.stringify({ | |
id: self.processIdentifier(), | |
name: self.name(), | |
//icon: self.icon(), | |
bundle: self.bundleIdentifier(), | |
active: self.isActive(), | |
hidden: self.isHidden(), | |
}, null, 4)}` | |
modalMaker(text, function(frame) { | |
let windowFrame = ( | |
(window && Space.active() in window.spaces()) | |
? frameToFlipped(frameCenterOf(window.frame())) | |
: frameCenterOf(Screen.main().flippedFrame()) | |
) | |
return frameCenterOfCenteringOther(windowFrame, frame) | |
return screenPointRelativeToRightOfFrame( | |
Screen.main().frame(), | |
{ x: frame.width, }, | |
) | |
}, { | |
duration: 1.0, | |
weight: 16, | |
}) | |
Phoenix.log("appDidActivate", text) | |
return console.log("appDidActivate", app, event, text) | |
}) | |
Event.on("appDidHide", function(app) { | |
return console.log("appDidHide", app) | |
}) | |
Event.on("appDidShow", function(app) { | |
return console.log("appDidShow", app) | |
}) | |
// Window | |
Event.on("windowDidOpen", function(win) { | |
return console.log("windowDidOpen", arguments) | |
}) | |
Event.on("windowDidClose", function(win) { | |
return //console.log("windowDidClose", arguments) | |
}) | |
Event.on("windowDidFocus", function(win, event) { | |
let self = win || Window.focused() | |
if(!self) return | |
Timer.after(0.1, function() { | |
return shouldMovePassiveMouseToCenterOfFrame(self.frame()) | |
}) | |
let text = `Window/Focus: ${JSON.stringify({ | |
//title: self.title(), | |
main: self.isMain(), | |
normal: self.isNormal(), | |
fullScreen: self.isFullScreen(), | |
minimized: self.isMinimized(), | |
visible: self.isVisible(), | |
topLeft: self.topLeft(), | |
size: self.size(), | |
frame: self.frame(), | |
}, null, 4)}` | |
modalMaker(text, function(frame) { | |
let windowFrame = self.frame() | |
return frameCenterOfCenteringOther(frameToFlipped(frameCenterOf(windowFrame)), frame) | |
return screenPointRelativeToRightOfFrame( | |
Screen.main().frame(), | |
{ x: frame.width, }, | |
) | |
}, { | |
duration: 1.0, | |
weight: 16, | |
}) | |
Phoenix.log("windowDidFocus", text) | |
return console.log("windowDidFocus", arguments) | |
}) | |
Event.on("windowDidMove", function(win) { | |
return console.log("windowDidMove", arguments) | |
}) | |
Event.on("windowDidResize", function(win) { | |
return console.log("windowDidResize", arguments) | |
}) | |
Event.on("windowDidMinimize", function(win) { | |
return console.log("windowDidMinimize", arguments) | |
}) | |
Event.on("windowDidUnminimize", function(win) { | |
return console.log("windowDidUnminimize", arguments) | |
}) | |
// TODO: Mouse | |
Event.on("mouseDidMove", function(point) { | |
lastMouseMoveTime = Date.now() | |
let win = Window.at(point) | |
let main = Screen.main() | |
if(win && Math.abs(Date.now() - Math.max(lastClickTimes)) > 3333) { | |
let screen = win.screen() | |
if(screen === main) { | |
win.focus() | |
} else { | |
win.raise() | |
} | |
} | |
return ({ | |
x: point.x, | |
y: point.y, | |
}) | |
}) | |
Event.on("mouseDidLeftClick", function(point) { | |
lastClickTimes[0] = Date.now() | |
return console.log(arguments) | |
}) | |
Event.on("mouseDidRightClick", function(point) { | |
lastClickTimes[1] = Date.now() | |
return console.log(arguments) | |
}) | |
Event.on("mouseDidLeftDrag", function(point) { | |
lastDragTimes[0] = Date.now() | |
return console.log(arguments) | |
}) | |
Event.on("mouseDidRightDrag", function(point) { | |
lastDragTimes[1] = Date.now() | |
return console.log(arguments) | |
}) | |
keyHandlers.push(Key.on('space', mod, function() { | |
return showInfo() | |
})) | |
keyHandlers.push(Key.on('§', mod, function(event) { | |
modalMaker(`Focus is here ±±\n${event.key} | ${event.modifiers.join("+")}`) | |
return | |
})) | |
keyHandlers.push(Key.on('n', mod, function() { | |
return screenMouseMoveRelative(-1) | |
})) | |
keyHandlers.push(Key.on('m', mod, function() { | |
return screenMouseMoveRelative(+1) | |
})) | |
keyHandlers.push(Key.on('v', mod, function() { | |
return screenMoveActiveWindowRelative(-1, true) | |
})) | |
keyHandlers.push(Key.on('b', mod, function() { | |
return screenMoveActiveWindowRelative(+1, true) | |
})) | |
keyHandlers.push(Key.on('w', mod, function() { return windowFocusQuickMoveByPointer("north") })) | |
keyHandlers.push(Key.on('s', mod, function() { return windowFocusQuickMoveByPointer("south") })) | |
keyHandlers.push(Key.on('a', mod, function() { return windowFocusQuickMoveByPointer("west") })) | |
keyHandlers.push(Key.on('d', mod, function() { return windowFocusQuickMoveByPointer("east") })) | |
keyHandlers.push(Key.on('up', mod, function() { return windowFocusQuickMoveByWindow("north") })) | |
keyHandlers.push(Key.on('down', mod, function() { return windowFocusQuickMoveByWindow("south") })) | |
keyHandlers.push(Key.on('left', mod, function() { return windowFocusQuickMoveByWindow("west") })) | |
keyHandlers.push(Key.on('right', mod, function() { return windowFocusQuickMoveByWindow("east") })) | |
function showInfo(duration=1) { | |
let screenMain = Screen.main() | |
Screen.all().forEach(function(screen, index) { | |
/* | |
Phoenix.log("info", index, JSON.stringify({ | |
mouseLoc: Mouse.location(), | |
screenFrame: screen.frame(), | |
screenFlipped: screen.flippedFrame(), | |
screenVisible: screen.visibleFrame(), | |
screenVisibleFlipped: screen.flippedVisibleFrame(), | |
}, null, 4)) | |
*/ | |
modalMaker( | |
JSON.stringify({ | |
index: index, | |
main: (screenMain === screen), | |
id: screen.identifier(), | |
windows: screen.windows().length, | |
spaces: screen.spaces().length, | |
}, null, 4), | |
function(frame) { | |
return frameCenterOfCenteringOther( | |
frameCenterOf(screen.frame()), | |
frame, | |
) | |
}, { | |
duration: 1.0, | |
weight: 16, | |
} | |
) | |
return | |
}) | |
let window = Window.focused() || Window.at(Mouse.location()) | |
if(!window) return | |
[ "north", "south", "west", "east" ].forEach(function(direction) { | |
return windowDisplayNeighboursInDirection(window, direction) | |
}) | |
Window.all().forEach(function(window, index) { | |
return | |
}) | |
return | |
} | |
function windowDisplayNeighboursInDirection(window, direction) { | |
return window.neighbours(direction).forEach(function(neighbour, index) { | |
modalMaker(`${direction} : ${index}`, function(frame) { | |
return frameCenterOfCenteringOther(frameToFlipped( | |
frameCenterOf(neighbour.frame())), | |
frame, | |
) | |
}, { | |
icon: neighbour.app().icon(), | |
duration: 1.0, | |
weight: 16, | |
}) | |
return | |
}) | |
} | |
if(false) | |
Timer.every(0.001, function() { | |
let loc = Mouse.location() | |
let text = `x:${parseInt(loc.x)}\ny:${parseInt(loc.y)}` | |
return modalMaker(text, function(frame) { | |
let pos = frameToFlipped(loc) | |
return { | |
x: pos.x - frame.width / 2 + 50, | |
y: pos.y - frame.height / 2 - 50, | |
} | |
}, 0.001, 10, 0.000000000001) | |
}) | |
showInfo() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment