Hammerspoon / hammerspoon

Staggeringly powerful macOS desktop automation with Lua
http://www.hammerspoon.org
MIT License
12.07k stars 583 forks source link

Window movements with hs.window are incorrect after opening native Keyboard Viewer #2794

Open cfal opened 3 years ago

cfal commented 3 years ago

Possibly related to https://github.com/Hammerspoon/hammerspoon/issues/2316 since it looks like it's related to animations, but Keyboard Viewer is not an electron app. Keyboard Viewer is the native MacOS on-screen keyboard which you can open from Accessibility or from "Show Keyboard Viewer" if you have the input icon in your menubar.

To reproduce:

  1. Bind some hs.window commands with animationDuration = 0, eg. I have:
    
    local function left_half()
    local rect = hs.screen.mainScreen():frame()
    rect.x = 0
    rect.w = rect.w / 2
    hs.window.focusedWindow():setFrame(rect, 0)
    end

local function right_half() local rect = hs.screen.mainScreen():frame() rect.x = rect.w / 2 rect.w = rect.w - rect.x hs.window.focusedWindow():setFrame(rect, 0) end



2. Open the TextEdit app. This also happens with every other app I tested with, but it's important that the app was opened before Keyboard Viewer was.
3. (optional) Test that setFrame commands with 0 animation duration happens instantly.
4. Open Keyboard Viewer
5. Close Keyboard Viewer
6. Invoke one of the functions that would cause the window's x coordinate to change
7. Observe that it's animated, and the x coordinate does not change.

Strangely enough, any app that is opened after Keyboard Viewer is closed is still able to be resized correctly.

Calling it repeatedly does eventually work, but once again it seems to be fighting against some other animations that's happening. Opening the Keyboard Viewer seems to enable them.
Rhys-T commented 1 year ago

This sounds like it's probably a result of the AXEnhancedUserInterface property getting enabled. AXEnhancedUserInterface is mostly a VoiceOver thing, but Keyboard Viewer - which got reworked into the Accessibility Keyboard at some point - seems to set it to true as well. Unfortunately, it has some weird side effects, like adding animations when you try to move/resize anything through the Accessibility API - and canceling those animations halfway through if you try to do a move immediately followed by a resize. See https://github.com/Hammerspoon/hammerspoon/issues/3224#issuecomment-1294359070 and replies for more info and workarounds.

Edit: I actually keep this function in my config so that I can clear that property after using the Keyboard Viewer:

function zapEnhancedUserInterface()
    for _, app in ipairs(hs.application.runningApplications()) do
        local ax = hs.axuielement.applicationElement(app)
        if ax.AXEnhancedUserInterface then
            print(app:name())
            ax.AXEnhancedUserInterface = false
        end
    end
end