Activate (focus) the first window (of any app) that contains "Name"

How useful would it be a macro where I can type "budget" in a prompt and it brings into focus the Budget.xls window.

KM already has this feature, but it only works for a Specific app. It would be very useful it it would work for any app.

1 Like

Not “any app” but “any running apps”

Maybe I’m blind, but I cannot find the Action you show in your image. I have searched in the KM Editor and in the KM wiki and don’t see it. In the KM Editor, what Category is this action in, and what is the exact name of it as it appears there?

It’s the “Manipulate a Window” action.

I would never have guessed, and although the options (operations) are listed in the KM Wiki, they seem easy to overlook (at least to me).
For everyone's benefit, here are the main options of the Manipulate a Window Action:

In my opinion it’s more convenient to manipulate windows with BetterTouchTool and gestures with magic mouse.

Hey Leonardo,

That’s doable with AppleScript and System Events.

------------------------------------------------------------
# Bring Named Window Forward.
------------------------------------------------------------
set winName to display dialog "Enter a Window Name:" default answer ""
set winName to "Keyboard Maestro"
set winNameList to {}

tell application "System Events"
  repeat with theApp in (processes whose background only is false)
    tell theApp
      set appName to its name
      set winList to name of (windows whose name contains "Keyboard Maestro")
    end tell
    if length of winList > 0 then
      repeat with winName in winList
        set contents of winName to (contents of winName) & tab & " --» " & tab & appName
      end repeat
      set winNameList to winNameList & winList
    end if
  end repeat
end tell

if winNameList ≠ {} then
  
  set theWindow to choose from list winNameList ¬
    with title "Windows With Designated Name" with prompt ¬
    "Pick One:" default items {item 1 of winNameList} ¬
    without empty selection allowed
  
  if theWindow ≠ false then
    set theWindow to item 1 of theWindow
    set AppleScript's text item delimiters to tab & " --» " & tab
    set {theWindow, theApp} to (get text items of theWindow)
    
    tell application "System Events"
      tell process theApp
        set frontmost to true
        tell window theWindow
          perform action "AXRaise"
        end tell
      end tell
    end tell
    
  end if
  
else
  beep
end if
------------------------------------------------------------

Try it from the Script Editor.app.

If you install Shane Stanley’s MyriadTables Library I could even make it halfway pretty.

-Chris

5 Likes

This is awesome, I can’t believe you took the time to do it Chris. Thank you so much, I hope others find this useful!

Very nice script, Chris. :sunglasses: Thanks for sharing.

That would be a real treat! :+1:

Just for fun and parallel reading, a very stripped-down JavaScript version which jumps straight into activating the first match found, without offering a menu of options:

(function () {
    'use strict';

    var a = Application.currentApplication(),
        se = Application("System Events"),
        sa = (a.includeStandardAdditions = true, a),
        o = ObjectSpecifier();

    var lstWins = [].concat.apply(
              [], se.processes.whose({
                _match: [o.backgroundOnly, false]
            })
            .windows.whose({
                _match: [o.name, {
                    _contains: sa.displayDialog("Window name:", {
                            withTitle: "Activate window by name",
                            defaultAnswer: '',

                        })
                        .textReturned
                }]
            })()
        ),
        oWin = lstWins.length ? lstWins[0] : undefined;

    if (oWin) {
        se.perform(oWin.actions.byName('AXRaise'));
    }
})();
2 Likes

Or a version which at least offers a simple menu for single or multiple selections:

Ver 03: updated to make app of raised window frontmost, and add app name to menu


// ver 0.4 brings single matches straight to the front
// ver 0.3 includes app name (before window name) in menu
// ver 0.2 makes app frontmost, as well as raising window
(function () {
    'use strict';

    function raiseWin(oWin, appSE) {
        (appSE || Application("System Events"))
        .perform(oWin.actions.byName('AXRaise'));
    
        oWin.attributes.byName('AXParent')
            .value()
            .frontmost = true;
    }

    var strTitle = "Activate windows by name",
        a = Application.currentApplication(),
        se = Application("System Events"),
        sa = (a.includeStandardAdditions = true, a),
        o = ObjectSpecifier();

    a.activate();

    var strText = sa.displayDialog("Part of window name:", {
            withTitle: strTitle,
            defaultAnswer: '',

        })
        .textReturned,
        lstWins = [].concat.apply(
          [], se.processes.whose({
                _match: [o.backgroundOnly, false]
            })
            .windows.whose({
                _match: [o.name, {
                    _contains: strText
              }]
            })()
        ),
        lngWins = lstWins.length;

    // VARIANT: OFFER MENU WHEN MATCHES ARE MULTIPLE
    if (lngWins > 0) {
        if (lngWins > 1) {
            var lstNames = lstWins.map(function (w) {
                    return w.attributes.byName('AXParent')
                        .value.name() + ' > ' + w.name();
                }),

                varChoice = sa.chooseFromList(lstNames, {
                    withTitle: strTitle,
                    withPrompt: "Matching '" + strText + "'",
                    defaultItems: lstNames[0],
                    multipleSelectionsAllowed: true
                });

            if (varChoice) {
                varChoice.map(function (s) {
                        return lstNames.indexOf(s)
                    })
                    .forEach(function (i) {
                        raiseWin(lstWins[i], se);
                    });
            }
        } else raiseWin(lstWins[0], se);
    }

})();
2 Likes

Thanks for sharing, Rob. :+1:

I really appreciate translations of AppleScript to JXA. They really help my learning of JXA.
I hope you won’t mind a few questions (if any) that I may have after reviewing and testing your JXA code.

1 Like

:open_mouth: This is heaps cool, I just found out about the “Execute Javascript for automation” action. Thanks for sharing!

Ver 0.2 updated (above) to make app of raised window frontmont

Thanks to Chris Stone for providing the AXParent attribute route from window to app

Manipulate a Window is richer than most other software tools by themselves! I’m still posting questions that get answers pointing to Manipulate a Window, and I’ve been using KM since QuicKeys toppled over years ago.