no way to choose screen with hs.canvas.new
idavydov opened this issue · comments
Iakov Davydov commented
Hi,
I would like to show canvas on the mainScreen (hs.screen.mainScreen
). Unfortunately, canvas is always created on the same screen (I'd guess primary screen).
Here's the code I'm using:
mycanvas = nil
hs.hotkey.bind({"control", "shift"}, "r", function()
if mycanvas ~= nil then
mycanvas:delete()
mycanvas = nil
return
end
c = require("hs.canvas")
local mode = hs.screen.mainScreen():currentMode()
mycanvas = c.new{x=0, y=0, w=mode.w, h=mode.h}:appendElements({
-- ....
}):show()
hs.timer.doWhile(... do something in a loop...)
end)
Xavier Valarino commented
You need to create your new canvas with the absolute X and Y coordinates of the screen, which can be negative or positive in relation to the primary screen.
Here is a working example:
hs.hotkey.bind({ 'control', 'shift' }, 'r', function()
local screenFrame = hs.screen.mainScreen():frame()
-- Use absolute coordinate space used by OSX/Hammerspoon when setting X and Y
local canvas = hs.canvas.new(screenFrame)
canvas
:appendElements({
type = 'rectangle',
action = 'fill',
fillColor = { red = 1, green = 0, blue = 1, alpha = 0.6 },
-- canvas children coordinates should be relative to the canvas
frame = { x = 0, y = 0, w = 200, h = 200 },
})
:show()
end)
Also note that while testing this code, some windows like Hammerspoon Console
didn't properly update the mainScreen coordinates. You may want to use the focusedWindow to get the correct screen as a work around.
-- Doesn't work with some windows like "Hammerspoon Console"
-- local screenFrame = hs.screen.mainScreen():frame()
-- This seems to work fine
local screenFrame = hs.window.focusedWindow():screen():frame()