GameMaker: Opening links in a new tab on HTML5

On some occasions you may want to open a link in a new tab a GameMaker' HTML5 game.

As simple as it may look, this presents a bit of a problem:

  • url_open opens links in the same tab.
  • url_open_ext can open links in a new tab, but triggers popup blocker.
  • clickables can open links in a new tab, but have to be repositioned manually.
    (particularly inconvenient if scaling-positioning the game for mobile browsers)
  • Adding an actual link (<a> element) into the game template allows to open links in a new tab, but requires basic understanding of JavaScript and HTML to hide/unhide dynamically.

url_open_ext is by far the most convenient of these, so let me explain why that does not work:

To prevent any page from being able to randomly open indefinitely large quantities of new tabs, the browser will automatically block attempts to open new tabs\windows unless they originate from user interaction (click event);

GameMaker handles events, and writes down new input states to later dispatch GML-level events at the right time and place (see event order). This means that your GML code inside a "Mouse Pressed" event does not count as originating from a user interaction (as it executes a few milliseconds later), and thus is not allowed to open new tabs (and do some other things).

However, with a bit of JS (and understanding of internal workings of GM), it is possible to accomplish the intended result, and this post is about that.

Extension' code

The extension consists of 2 GML scripts, 1 GML macro, and 1 JS function.

The GML side (browser_click_handler.gml) is as following:


#define gmcallback_browser_click_handler
/// ()
//#browser_click_handler global.g_browser_click_handler
var q = browser_click_handler;
if (script_exists(q)) script_execute(q);

#define browser_click_handler_init_gml
/// ()
browser_click_handler = -1;
if (browser_click_handler_init_js()) {
    gmcallback_browser_click_handler();
}

Here you can see:

  • A macros with name browser_click_handler and value global.g_browser_click_handler.
    This essentially makes a global variable with auto-completion (related post).
  • gmcallback_browser_click_handler is a GML script that will be called when the user clicks somewhere. gmcallback_ prefix ensures that it will not be automatically minified (and thus available as window.gml_Script_gmcallback_browser_click_handler); the script itself retrieves the script index from the aforementioned global variable and calls the script if it's valid.
  • browser_click_handler_init_gml is a GML script that should be set as "initialization" script for the extension file. It sets the global variable to a default value, calls the JS side init function, and includes a reference to the gmcallback_ script to prevent it from being removed compilation-time in older versions of GMS due to lack of apparent use.

JavaScript side of things is a single function that binds the gmcallback_ script to the click event:

///
function browser_click_handler_init_js() {
    window.addEventListener("click", window.gml_Script_gmcallback_browser_click_handler);
    return 0;
}

If your canvas has a fixed ID, you could replace window by document.getElementById("yourCanvasID) to have the code not trigger when clicking outside the canvas (if it does not cover the entire page).

Using the extension

Once the extension is ready and imported, the use is straightforward: assign a script into the browser_click_handler variable when you need to,

browser_click_handler = scr_clicked;

and handle new-tab-related actions from there:

/// scr_clicked()
with (obj_link_button) if (position_meeting(mouse_x, mouse_y, id)) {
    url_open_ext(url, "_blank");
}

(in this case, having obj_link_button' instances open their url in new tab when clicked)

Much like room creation code, the script will execute for no particular instance.

And that's it. A pre-compiled extension (along with a live demo) can be found on itch.io:

Download (itch.io)

Have fun!

Related posts:

11 thoughts on “GameMaker: Opening links in a new tab on HTML5

  1. Hey Hi,
    it seems really strange to me but this extension doesn’t work for me in Chrome on Android.
    I’m very new to JavaScript and everything else except gml but to my understanding, it should work just the same.
    Do you know why?
    This extension would be a million times better than working with game makers clickables!
    I would really appreciate your Help!
    Thank you so much!

    • The recent versions of Chrome changed what user actions are considered significant enough for things like page navigation, so this just doesn’t work anymore. I’ve spent a few hours looking for workarounds for this the first time someone mentioned this, but there was no conclusion to that.

      • Is this handler completely obsolete then? I’m trying to find a way to copy text to clipboard but it wont work on mobile browsers due to what i believe is the same issue as opening new tabs – not detecting user interaction.

        So I tried this extension but no luck. Is there a workaround? Thanks!

        • There are now additional restrictions like clipboard manipulation only being allowed in webpages served over HTTPS, but also it’s hard to guess what goes with mobile without going through effort to set up a remote content debugger for Chrome/Safari.

          Isn’t clipboard_set_text supposed to request user permission and copy text to clipboard these days?

          • Yes clipboard_set_text works perfect in non-mobile browsers but i get a ‘navigator.permissions.query’ error on mobile chrome (ios).

            An update to the issue is that this extension actually still worked fine to open a new tab on mobile chrome when tested, but when i change to code to clipboard_set_text instead of a browser link the said error occurs.

            I don’t exactly know if any of that info is useful but thanks for the help and quick response anyways!

          • Another Update:

            When using this extension and NOT using game maker’s built in clipboard_set_text, but instead making my own simple javascript extension that does the same thing, just in javascript, I got my problem working.

            Sorry this was a little off topic of the subject matter but I thought it applied in it’s own way and was the closest post i could find to my issue. Thanks so much again! Your name will go in the special thanks!

            • HTML5 runtime is on GitHub now so perhaps you could open an issue and include your workaround – the clipboard functions were added relatively recently for the target.

  2. Pingback: A summary of my GameMaker assets

  3. Oh man, I want this one. It’s so frustrating itch.io downloads doesn’t work for me even selecting “Enable alternate download mode” :(

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.