No internet connection
  1. Home
  2. How to

Way to access these menu Items?

By Owen Granich-Young @Owen_Granich_Young
    2024-10-23 17:07:16.628Z

    Do they have a name for click menu item maybe?

    • 7 replies
    1. Kitch Membery @Kitch2024-10-23 17:38:18.717Z

      Hi @Owen_Granich_Young,

      For Application specific items, they usually have a Roll of "AXMenuBarItem" and a Subrole of "AXMenuExtra", and are attached to the Application.

      What are you trying to achieve specifically?

      1. Kitch Membery @Kitch2024-10-23 17:40:39.784Z

        I will say though, that they are often hard to access.

        1. Chad Wahlbrink @Chad2024-10-23 17:49:46.583Z

          If you can discover the bundle id, it's sometimes possible to automate these apps.

          For instance, I can automate CleanShot X with this:

          
          sf.ui.app("com.getcleanshot.app-setapp").getElement('AXExtrasMenuBar').popupMenuSelect({menuPath:["Hide Desktop Icons"]})
          

          Shout out to @raphaelsepulveda for cracking this code a while back!

          You can find the bundle id by running something like this in terminal:

          osascript -e 'id of app "CleanShot X"'
          

          https://forum.soundflow.org/-2296#post-3

          1. niftty, tbh QUIT and Open the app is working fine, was just wondering if Enable Disable would be sneakier.

          2. Chad Wahlbrink @Chad2024-10-23 17:53:46.762Z

            Some menu bar apps (like Dropbox) use custom GUI's that don't automate well like this.

            You can sometimes use .popupMenuSelect({isOption:true}) to access more functions for these type of apps.

            Here's an example of fetching paths for the Dropbox menubar app:

            log(sf.ui.app("com.getdropbox.dropbox").getElement('AXExtrasMenuBar').popupMenuFetchAllItems({isOption:true}).menuItems.map(x => x.path))
            
            1. Chad Wahlbrink @Chad2024-10-23 19:07:07.146Z

              Also for fun, here are some ways to access some of the macOS Control Center Menu Bar Items

              Change Focus Mode

              
              // Set Focus Mode
              sf.ui.app('com.apple.controlcenter').getElement("AXExtrasMenuBar").getFirstWithTitle('Focus').elementClick()
              
              sf.ui.app('com.apple.controlcenter').windows[0].children.whoseTitle.is('Work').first.elementWaitFor().element.elementClick({asyncSwallow:true});
              
              sf.keyboard.press({keys:'escape'})
              

              Set Sound Output

              sf.ui.app('com.apple.controlcenter').getElement("AXExtrasMenuBar").getFirstWithTitle('Sound').elementClick()
              
              sf.ui.app('com.apple.controlcenter').windows[0].children.whoseRole.is('AXScrollArea').first.elementWaitFor()
              
              sf.ui.app('com.apple.controlcenter').windows[0].children.whoseRole.is('AXScrollArea').first.children.whoseTitle.is('Studio Display Speakers').first.elementClick({asyncSwallow:true})
              
              sf.ui.app('com.apple.controlcenter').getElement("AXExtrasMenuBar").getFirstWithTitle('Sound').elementClick();
              

              NOTE- A Better Way to Set Audio Devices

              List your DeviceIDs to the SF Log with:

              log(sf.audio.getAudioDevices().devices)
              

              Outputs this to the log:

              [
              {
                      "DeviceId": 126,
                      "DeviceName": "Universal Audio Thunderbolt",
                      "IsActiveInput": false,
                      "IsActiveOutput": false
                  }
              ]
              

              Then you can use this to set the audio device:

              sf.audio.selectAudioDevice({deviceId:126})
              

              Toggle Audio Devices

              Or this to toggle Audio Devices:

              
              // Use `log(sf.audio.getAudioDevices().devices)` to get device IDs
              let device1 = 126;
              let device2 = 50;
              
              let activeAudioDevice = sf.audio.getAudioDevices().devices.filter(x => x.isActiveOutput)[0]
              
              if (activeAudioDevice['DeviceID'] == device1) {
                  sf.audio.selectAudioDevice({ deviceId: device2 })
              } else {
                  sf.audio.selectAudioDevice({ deviceId: device1 })
              }
              
              
              1. MMatt Friedman @Matt_Friedman
                  2024-11-01 16:03:07.699Z

                  I've been needing this for the longest time! Thank you for this!