How to close on screen keyboard from menu bar option "A" near the spotlight search

Solution 1:

Update (again) per Comment

This first block of example AppleScript code conditionally clicks the Input menu on the Menu Bar only when the Hide Keyboard Viewer menu item exists, thus hiding the Keyboard Viewer.

tell application "System Events"
    tell application process "TextInputMenuAgent"
        tell menu bar item 1 of menu bar 2
            if menu item "Hide Keyboard Viewer" of menu 1 exists then
                set menuItemExists to true
                ignoring application responses
                    click
                end ignoring
            else
                set menuItemExists to false
            end if
        end tell
    end tell
end tell

if menuItemExists then
    do shell script "killall 'System Events'"
    tell application "System Events"
        tell application process "TextInputMenuAgent"
            tell menu 1 of menu bar item 1 of menu bar 2
                click menu item "Hide Keyboard Viewer"
            end tell
        end tell
    end tell
end if




Update per Comment

tell application "System Events"
    tell application process "TextInputMenuAgent"
        tell menu bar item 1 of menu bar 2
            ignoring application responses
                click
            end ignoring
        end tell
    end tell
end tell

do shell script "killall 'System Events'"

tell application "System Events"
    tell application process "TextInputMenuAgent"
        tell menu 1 of menu bar item 1 of menu bar 2
            click (every menu item whose name contains "Viewer")
        end tell
    end tell
end tell

Note that the example AppleScript code shown above contains no error handling and assume the Input menu exist on the Menu Bar


Note: The example AppleScript code is just that and does not contain any error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.


Answer to Original Question

The example AppleScript code, show below, was tested under macOS Catalina with Language & Region set to English (US) in System Preferences and worked for me as coded, when the Keyboard Viewer was opened from the Input menu on the Menu Bar.

Testing was done from Script Editor, as well as when used as a shell script from Terminal using a #!/usr/bin/osascript shebang and made executable with chmod +x filename.

Unfortunately, I was unable to use basic vanilla AppleScript to click the Close button as it is apparently not allowed with the Keyboard Viewer window, so this script makes use of a third-party utility named cliclick and was placed in /usr/local/bin/.

The Keyboard Viewer window can be in two different states on screen, normal window and minimized window as illustrated in the images below:

enter image description here

enter image description here

As coded it will work with both window states and close the window by ascertaining the position and size on the screen of the Close button, and if necessary the Keyboard button too, and then use cliclick to click the button(s).


Example AppleScript code:

tell application "System Events"
    if (exists window "Panel" of ¬
        application process "Assistive Control") then
        
        if (exists button "Close" of window "Panel" of ¬
            application process "Assistive Control") then
            
            tell application process "Assistive Control"
                
                set closeButtonPositionSize to {position, size} of ¬
                    button "Close" of window "Panel"
                my clickButton(closeButtonPositionSize, "Close")
                
            end tell
            
        else if (exists button "Keyboard" of group 1 of window "Panel" of ¬
            application process "Assistive Control") then
            
            tell application process "Assistive Control"
                
                set keyboardButtonPositionSize to {position, size} of ¬
                    button "Keyboard" of group 1 of window "Panel"
                my clickButton(keyboardButtonPositionSize, "Keyboard")
                
                repeat until (exists button "Close" of window "Panel")
                    delay 0.01
                end repeat
                delay 0.5
                
                set closeButtonPositionSize to {position, size} of ¬
                    button "Close" of window "Panel"
                my clickButton(closeButtonPositionSize, "Close")
                
            end tell
            
        end if
    end if
end tell


to clickButton(buttonPositionSize, buttonName)
    set xyPos to item 1 of buttonPositionSize
    set xySize to item 2 of buttonPositionSize
    set addPix to (item 1 of xySize) / 4 as integer
    set xPos to (item 1 of xyPos) + addPix
    set yPos to (item 2 of xyPos) + addPix
    
    set shellClickCloseButtonCMD to ¬
        {"/usr/local/bin/cliclick -r c:", ¬
            xPos, ",", yPos} as string
    
    set shellClickKeyboardButtonCMD to ¬
        {"/usr/local/bin/cliclick -r m:", ¬
            xPos, ",", yPos, space, "w:125", ¬
            space, "c:", xPos, ",", yPos} as string
    
    if buttonName is "Close" then
        do shell script shellClickCloseButtonCMD
    else if buttonName is "Keyboard" then
        do shell script shellClickKeyboardButtonCMD
        do shell script shellClickCloseButtonCMD
    end if
end clickButton