`Window.focused().topLeft()` returns `Point` relative to `Screen` with menu bar
ptrkstr opened this issue · comments
- Version: 3.0.0 (127)
- macOS: 12.3 (21E230)
Steps:
- Configure display to the following:
- Configure
.phoenix.js
script to the following:
Key.on('q', ['ctrl', 'option'], () => {
const frame = Window.focused().topLeft();
Phoenix.notify(`${frame.x} ${frame.y}`)
})
- Drag a window to the top left of the menu bar screen
- Press ctrl+option+q and observe notification:
✅ 0, 38
- Drag a window to the top left of the top screen
- Press ctrl+option+q and observe notification:
❌ -434, -1415
Expected:
0, 38
Observed:
-434, -1415
Notes:
If the menu bar is moved to the top screen, the correct values are observed when pressing ctrl+option+q when a window is in the top screen.
I noticed that topLeft
uses NSAccessibilityPositionAttribute
which doesn't provide much documentation.
The position in points of the element's lower-left corner in screen-relative coordinates (NSValue).
However I believe it's the same as kAXPositionAttribute
:
The global screen coordinates of the top-left corner of this accessibility object. Note that the coordinates 0,0 represent the top-left corner of the screen that displays the menu bar. All accessibility objects that have a screen position (in other words, are visible on the screen) should include this attribute.
If this is the case @kasper, does Phoenix currently offer a way to convert the Window.focused
coordinates to Screen.main
coordinates?
Closing the issue as I believe this is how it's meant to behave.
@ptrkstr Hello! So as you figured it out, all the screens together combine a massive coordinate system, depending on your display configuration. Therefore you need to calculate the positions based on the origin.
Thanks for the great software @kasper , would you consider signing up for github sponsors to make it easier for people to sponsor it?
I come across this as I wanted to define the following keys (in combination with ctrl
+ option
):
q,w,e
a,s,d
z,x,c
as:
top left, top, top right
left, maximise, right
bottom left, bottom, bottom right
relative to the screen you're on.
For anyone else that comes across this, here's the config:
function frame() {
return Window.focused().screen().flippedFrame();
}
// top left
Key.on('q', ['ctrl', 'option'], () => {
Window.focused().setFrame({ x: frame().x, y: frame().y, width: frame().width / 2, height: frame().height / 2 });
})
// top
Key.on('w', ['ctrl', 'option'], () => {
Window.focused().setFrame({ x: frame().x, y: frame().y, width: frame().width, height: frame().height / 2 });
})
// top right
Key.on('e', ['ctrl', 'option'], () => {
Window.focused().setFrame({ x: frame().x + (frame().width / 2), y: frame().y, width: frame().width / 2, height: frame().height / 2 });
})
// left
Key.on('a', ['ctrl', 'option'], () => {
setLeft(Window.focused());
})
// maximise
Key.on('s', ['ctrl', 'option'], () => {
Window.focused().maximise();
})
// right
Key.on('d', ['ctrl', 'option'], () => {
setRight(Window.focused());
})
// bottom left
Key.on('z', ['ctrl', 'option'], () => {
Window.focused().setFrame({ x: frame().x, y: frame().y + (frame().height / 2), width: frame().width / 2, height: frame().height / 2 });
})
// bottom
Key.on('x', ['ctrl', 'option'], () => {
Window.focused().setFrame({ x: frame().x, y: frame().y + (frame().height / 2), width: frame().width, height: frame().height / 2 });
})
// bottom right
Key.on('c', ['ctrl', 'option'], () => {
Window.focused().setFrame({ x: frame().x + (frame().width / 2), y: frame().y + (frame().height / 2), width: frame().width / 2, height: frame().height / 2 });
})
function setLeft(window) {
window.setFrame({ x: frame().x, y: frame().y, width: frame().width / 2, height: frame().height });
}
function setRight(window) {
window.setFrame({ x: frame().x + (frame().width / 2), y: frame().y, width: frame().width / 2, height: frame().height });
}
// split last 2 windows vertically
Key.on('v', ['ctrl', 'option'], () => {
const windows = Window.recent();
if (windows.length < 2) {
return;
}
setLeft(windows[0]);
setRight(windows[1]);
})
@ptrkstr Very simple and nice! 😄 I haven’t signed up for GitHub sponsorship yet, I would need to check what the tax implications look like. Thanks for the thought! ❤️