fix(window-focus): preserve single-click activation

This commit is contained in:
AquaMorph committed 2026-10-30 11:20:09 -04:00
1 parent 9a3b37d5a8
commit 017bf12b43
4 files changed
+60 -17

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@ default-root-container-layout = 'tiles'
default-root-container-orientation = 'auto'
enable-normalization-flatten-containers = true
enable-normalization-opposite-orientation-for-nested-containers = true
focus-follows-mouse.enabled = true
focus-follows-mouse.enabled = false
key-mapping.preset = 'qwerty'
persistent-workspaces = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
+45
View File
@@ -0,0 +1,45 @@
-- 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
+2
View File
@@ -1,5 +1,6 @@
-- Placement rules inferred from the running windows on this Mac.
require("hs.ipc")
local clickthrough = require("clickthrough")
local spaces = require("hs.spaces")
local log = hs.logger.new("placement", "info")
@@ -190,6 +191,7 @@ windowPlacement = {
}
windowPlacement.menu:setTitle("Windows")
windowPlacement.menu:setMenu({
{title = "Toggle single-click window activation", fn = clickthrough.toggle},
{title = "Reapply placement rules", fn = restore},
{title = "Reload configuration", fn = hs.reload},
{title = "Open Console", fn = hs.openConsole},