Paste a URL

I am trying to paste an url. This works (Safari).

Unfortunately this does not. Is there anything I can do differently for the Vivaldi browser? Thanks!

Hopefully this helps.

Thanks @noisneil! Yes, that works. But which is the front browser when I have several open at the same time? And none of these browsers is the front app? :joy:

As Vivaldi is Chromium-based, maybe you can change KM preferences to us it.

If you don't want to do that, then you can maintain a macro that always stores Vivaldi's URL as a global variable, triggered by window change.

I'll take a look at it, thanks!

1 Like

I think if you put a macro like this in your Vivaldi-specific group, it should do the job.

You could also put this in an Execute JavaScript for Automation action, assigning the result to a KM variable.

(in this form it fetches both title and url, but it's easily edited to fetch only one of those)

(It doesn't depend on Vivaldi being the foremost browser, and warns you if Vivaldi is not running)

Expand disclosure triangle to view JS source
(() => {
    "use strict";

    const bundleID = "com.vivaldi.Vivaldi";

    ObjC.import("AppKit");

    // Title and URL from front tab of identified browser
    // (if it is running).

    // Rob Trew @2023
    // Ver 0.01

    // main :: IO ()
    const main = () =>
        either(
            alert(`Active ${bundleID} tab`)
        )(
            titleAndURL => titleAndURL
        )(
            bindLR(
                isRunning(bundleID)
                    ? Right(
                        Application(bundleID).windows.at(0)
                    )
                    : Left(`${bundleID} not running.`)
            )(
                window => fmapLR(
                    tab => `[${tab.title()}](${tab.url()})`
                )(
                    window.exists()
                        ? Right(
                            window[
                            [
                                "com.apple.Safari",
                                "com.kagi.kagimacOS"
                            ]
                            .includes(bundleID)
                                ? "currentTab"
                                : "activeTab"
                            ]()
                        )
                        : Left(`No active tab found in ${bundleID}`)
                )
            )
        );


    // ----------------------- JXA -----------------------

    // alert :: String => String -> IO String
    const alert = title =>
        s => {
            const sa = Object.assign(
                Application("System Events"), {
                    includeStandardAdditions: true
                });

            return (
                sa.activate(),
                sa.displayDialog(s, {
                    withTitle: title,
                    buttons: ["OK"],
                    defaultButton: "OK"
                }),
                s
            );
        };


    // isRunning :: String -> IO Bool
    const isRunning = appBundleID => {
        const uw = ObjC.unwrap;

        return uw(
            $.NSWorkspace.sharedWorkspace
            .runningApplications
        )
        .map(x => uw(x.bundleIdentifier))
        .includes(appBundleID);
    };


    // --------------------- GENERIC ---------------------

    // Left :: a -> Either a b
    const Left = x => ({
        type: "Either",
        Left: x
    });

    // Right :: b -> Either a b
    const Right = x => ({
        type: "Either",
        Right: x
    });

    // bindLR (>>=) :: Either a ->
    // (a -> Either b) -> Either b
    const bindLR = m =>
        mf => m.Left ? (
            m
        ) : mf(m.Right);

    // either :: (a -> c) -> (b -> c) -> Either a b -> c
    const either = fl =>
        // Application of the function fl to the
        // contents of any Left value in e, or
        // the application of fr to its Right value.
        fr => e => e.Left ? (
            fl(e.Left)
        ) : fr(e.Right);

    // fmapLR (<$>) :: (b -> c) -> Either a b -> Either a c
    const fmapLR = f =>
        // Either f mapped into the contents of any Right
        // value in e, or e unchanged if is a Left value.
        e => "Left" in e ? (
            e
        ) : Right(f(e.Right));

    return main();
})();
2 Likes

Thanks @ComplexPoint. It does what you explain.

But I just want the url. I don't understand anything about scripts like this unfortunately. How to delete the "extra part"?

If you just want the URL, modify this line

tab => `[${tab.title()}](${tab.url()})`

to

tab => `${tab.url()}`
1 Like

:+1: Thank you!

1 Like

( or even just tab => tab.url() )

1 Like

In case it's food for thought... I find it useful to keep a global variable updated with the name of the most recently used browser.

Triggers: one for each browser upon activation:
This application... [browser name] ... activates

Action: set the global variable to %Application%1%.

Actually, you can already get this with the FrontBrowser token.

True... but it doesn't work for all browsers. Awkward customers include Firefox and Orion.

Yes, it only works in browsers that Keyboard Maestro is compatible with, which include Chrome-like and Safari-like browsers (and could include other browsers that have reasonable AppleScript support, but I'm not aware of any that don't fall in to the Chrome/Safari camps).

Yes, I was just throwing the idea in as food for thought for the OP, since I find my last_web_browser_used (naming is hard...) variable useful since it can cover all cases.

I have just run tests again, and it appears that Orion (which uses WebKit) is still an exception, as previously discussed.