mirror of
https://github.com/AquaMorph/dotfiles.git
synced 2026-11-03 08:17:59 +00:00
46 lines
1.9 KiB
Lua
46 lines
1.9 KiB
Lua
-- Focus on mouse-down, before macOS delivers the original click to the app.
|
|
-- Never synthesize an extra click: controls that accept first mouse must not fire twice.
|
|
local clickthrough = {}
|
|
local ax = require("hs.axuielement")
|
|
local log = hs.logger.new("clickthrough", "warning")
|
|
|
|
local function focusClickedWindow(event)
|
|
-- Leave modified clicks (context menus, background links, etc.) unchanged.
|
|
if next(event:getFlags()) then return false end
|
|
local element = ax.systemWideElement():elementAtPosition(event:location())
|
|
if not element then return false end
|
|
local role = element:attributeValue("AXRole")
|
|
if role == "AXMenu" or role == "AXMenuItem" or role == "AXMenuBarItem"
|
|
or role == "AXMenuBar" then return false end
|
|
|
|
local windowElement = element:attributeValue("AXWindow")
|
|
if not windowElement and role == "AXWindow" then windowElement = element end
|
|
local window = windowElement and windowElement:asHSWindow()
|
|
if not window or not window:isStandard() then return false end
|
|
local focused = hs.window.focusedWindow()
|
|
if not focused or focused:id() ~= window:id() then window:focus() end
|
|
return false
|
|
end
|
|
|
|
clickthrough.tap = hs.eventtap.new({hs.eventtap.event.types.leftMouseDown}, function(event)
|
|
local ok, err = pcall(focusClickedWindow, event)
|
|
if not ok then log.w(tostring(err)) end
|
|
return false -- Always pass through the original click, including on errors.
|
|
end)
|
|
|
|
function clickthrough.toggle()
|
|
clickthrough.enabled = not clickthrough.enabled
|
|
if clickthrough.enabled then clickthrough.tap:start() else clickthrough.tap:stop() end
|
|
end
|
|
|
|
clickthrough.enabled = true
|
|
clickthrough.tap:start()
|
|
-- macOS can disable event taps after sleep or a slow accessibility response.
|
|
clickthrough.watchdog = hs.timer.doEvery(5, function()
|
|
if clickthrough.enabled and not clickthrough.tap:isEnabled() then
|
|
clickthrough.tap:start()
|
|
end
|
|
end)
|
|
|
|
return clickthrough
|