hammerspoon icon indicating copy to clipboard operation
hammerspoon copied to clipboard

no way to choose screen with hs.canvas.new

Open idavydov opened this issue 2 years ago • 1 comments

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)


idavydov avatar Jun 08 '22 13:06 idavydov

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()

xaviervalarino avatar Sep 12 '22 22:09 xaviervalarino