Floating webview pinned to a specific window on specific position / alternatives

Hello @Andreas_Hegenberg , long time no see! I might have not been as active on the forum but I am still watching over the changelog and I’m gonna be a lifetime user for sure, I can’t use a mac without BTT basically. Thanks again for your great work throughout the years.

I wanted to see if I can satisfy a need that I have right now with BTT somehow. Basically I do work on many threads / tasks on my day to day job. Ultimately I’m working with tons of open Chrome windows and I keep the resources related to a specific task in a dedicated window each.

The thing is it’s hard for me to distinguish those windows from each other when they stack a lot. I know that we can name a window (which is visible in the mission control later) but I thought I could perhaps create something like a “floating view pinned to a specific window” so it floats ontop of that window, is positioned somewhere ontop of it, and I can add a text / badge / whatever for me to recognise the window easily. I’m open to hear another suggestions but I do like working with individual windows and for example Chrome tab grouping doesnt work as well for me.

So basically I need to:

  • “mark the window” somehow
  • be able to distingiush the windows from each other at glance

Is there a way to do that right now? Or perhaps you might have some other ideas? Thanks again!

Great to see you again @Worie ! I spent so many hours back in 2018 reading your posts on this forum when I was learning how to use BTT.

1 Like

This depends a bit. What can be achieved easily is to show the name of the frontmost window.

Here is an example for that (floating at the top right of the window):

Note: I just noticed a problem I introduced with one of the previous versions. For this example to work well please use 5.649

chrome-naming.bttpreset (19.3 KB)

This could of course be scripted to show different icons etc. depending on the window name as well.

It gets more complicated if you want to have multiple of these showing also for background windows. I have recently started adding support for this but need to make a few more changes to make this reliable and accessible via the UI. Maybe I get some time to experiment with that a bit more later!

Wow thank you @fortred2 that’s really nice to hear! I did not think people I will get recognised lol. Thank you!

@Andreas_Hegenberg thank you for getting back to me so quickly! I was able to play around with it (although probably broken a few things too as my BTT was crashing whenever I focused on Chrome - I think i tried to override a readonly variable :sweat_smile: )

With what you came up with I was able to progress and I think this will work for me even without the background windows having that floating menu (I can always cycle with CMD+~) but I noticed that I cannot get the BTTActiveWindowNumber from JS reliably. It seems to either get stuck or cached? When I rerun the script every second, I’m getting the right value, but without it the moment Chrome gets focused, it keeps the floating menu text I’ve set to be that variable across windows. I think it will be easier to show an example;


async function itemScript(itemUUID) {
	function delay(ms) {
		return new Promise(resolve => setTimeout(resolve, ms));
	}

	function stringToColour(str) {
		let hash = 0;
		str.split('').forEach(char => {
			hash = char.charCodeAt(0) + ((hash << 5) - hash)
		})
		let colour = '#'
		for (let i = 0; i < 3; i++) {
			const value = (hash >> (i * 8)) & 0xff
			colour += value.toString(16).padStart(2, '0')
		}
		return colour
	}

	// do {
		try {
			await delay(100);
			const focusedWindowTitle = await get_number_variable({variable_name:'BTTActiveWindowNumber'});
			let content = 	{
				BTTMenuItemBackgroundColor : stringToColour(String(focusedWindowTitle) || ''),
				BTTMenuItemText: `{BTTActiveWindowNumber}|${focusedWindowTitle}`,
			};
			return JSON.stringify(content);
		} catch (error) {
		
			return JSON.stringify({
				BTTMenuItemText: error.message,
			});

		}

	// } while (true);

}


{BTTActiveWindowNumber}|${VARIABLE_FETCHED_FROM_WITHIN_FUNCTION}

So I basically show the same variable through either the magic template {VAR_NAME} or by actual value fetched by get_number_variable. Without the refresh every second this is what happens:

image
I wanted to use ActiveWindowNumber as an ID that I’ll store later to identify the groups. Do you have any workarounds in mind? I do understand now that the JS run when showing the menu item is not “running in the background” but probably dies when a function returns a value.

I'm not sure I 100% understand your requirements, but I took a stab at creating what I think you're trying to achieve.

I created a Floating Menu with a single item that contains a JS script that runs every second. The script changes the background color of the item based on the the window ID obtain from the chrome-cli. Here's the script, followed by some screenshots:

// --- tiny helpers ---
function hash32(str) { // FNV-1a (compact)
  let h = 0x811c9dc5 >>> 0;
  for (let i = 0; i < str.length; i++) {
    h ^= str.charCodeAt(i);
    h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;
  }
  return h >>> 0;
}

function hslToRgb(h, s, l) { // h in [0,360), s,l in [0,1]
  const c = (1 - Math.abs(2 * l - 1)) * s;
  const hp = (h % 360) / 60;
  const x = c * (1 - Math.abs((hp % 2) - 1));
  let r = 0, g = 0, b = 0;
  if (hp < 1)       { r = c; g = x; }
  else if (hp < 2)  { r = x; g = c; }
  else if (hp < 3)  { g = c; b = x; }
  else if (hp < 4)  { g = x; b = c; }
  else if (hp < 5)  { r = x; b = c; }
  else              { r = c; b = x; }
  const m = l - c / 2;
  return [
    Math.round((r + m) * 255),
    Math.round((g + m) * 255),
    Math.round((b + m) * 255)
  ];
}

function stringToBttRgba(str, alpha = 0.7) {
  const h = hash32(String(str));
  // Golden-angle spacing for better color spread between nearby values
  const hue = (h * 137.508) % 360;
  const s = 0.72;
  const l = 0.46;
  const [r, g, b] = hslToRgb(hue, s, l);
  return `${r},${g},${b},${alpha}`;
}

// --- main BTT script ---
async function itemScript(itemUUID) {
  try {
    const cfg = {
      script: 'OUTPUT_FORMAT=json /opt/homebrew/bin/chrome-cli info',
      launchPath: '/bin/bash',
      parameters: '-c'
    };
    const raw = await runShellScript(cfg);
    const data = JSON.parse(raw);

    const id = String(data.id ?? 'unknown');
    const rgba = stringToBttRgba(id, 0.7);

    const content = {
      BTTMenuItemBackgroundColor: rgba,
      BTTMenuItemText: `${id} | ${rgba}`
    };

    return JSON.stringify(content);
  } catch (err) {
    return JSON.stringify({
      BTTMenuItemText: `err: ${err && err.message ? err.message : String(err)}`
    });
  }
}



[
  {
    "BTTLastUpdatedAt" : 1758674829.384366,
    "BTTTriggerType" : 767,
    "BTTTriggerTypeDescriptionReadOnly" : "Floating Menu",
    "BTTTriggerClass" : "BTTTriggerTypeFloatingMenu",
    "BTTUUID" : "2F2C39DA-3569-41B7-9FF5-F279C56CDD61",
    "BTTOrder" : 0,
    "BTTTriggerName" : "Floating Menu: no-name-2F2C39D",
    "BTTMenuItems" : [
      {
        "BTTLastUpdatedAt" : 1758674829.3843789,
        "BTTTriggerType" : 773,
        "BTTTriggerTypeDescription" : "Standard Item",
        "BTTTriggerParentUUID" : "2F2C39DA-3569-41B7-9FF5-F279C56CDD61",
        "BTTTriggerClass" : "BTTTriggerTypeFloatingMenu",
        "BTTUUID" : "D86A40F1-57FA-4985-A053-281CC2AD600C",
        "BTTOrder" : 0,
        "BTTTriggerName" : "Menu Item: no-name-D86A40F",
        "BTTMenuConfig" : {
          "BTTMenuItemBorderColorDark" : "255.000000, 255.000000, 255.000000, 255.000000",
          "BTTMenuItemIconColor1" : "255.000000, 255.000000, 255.000000, 255.000000",
          "BTTMenuScriptSettings" : {
            "BTTScriptType" : 3,
            "BTTAppleScriptString" : "\/\/ --- tiny helpers ---\nfunction hash32(str) { \/\/ FNV-1a (compact)\n  let h = 0x811c9dc5 >>> 0;\n  for (let i = 0; i < str.length; i++) {\n    h ^= str.charCodeAt(i);\n    h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;\n  }\n  return h >>> 0;\n}\n\nfunction hslToRgb(h, s, l) { \/\/ h in [0,360), s,l in [0,1]\n  const c = (1 - Math.abs(2 * l - 1)) * s;\n  const hp = (h % 360) \/ 60;\n  const x = c * (1 - Math.abs((hp % 2) - 1));\n  let r = 0, g = 0, b = 0;\n  if (hp < 1)       { r = c; g = x; }\n  else if (hp < 2)  { r = x; g = c; }\n  else if (hp < 3)  { g = c; b = x; }\n  else if (hp < 4)  { g = x; b = c; }\n  else if (hp < 5)  { r = x; b = c; }\n  else              { r = c; b = x; }\n  const m = l - c \/ 2;\n  return [\n    Math.round((r + m) * 255),\n    Math.round((g + m) * 255),\n    Math.round((b + m) * 255)\n  ];\n}\n\nfunction stringToBttRgba(str, alpha = 0.7) {\n  const h = hash32(String(str));\n  \/\/ Golden-angle spacing for better color spread between nearby values\n  const hue = (h * 137.508) % 360;\n  const s = 0.72;\n  const l = 0.46;\n  const [r, g, b] = hslToRgb(hue, s, l);\n  return `${r},${g},${b},${alpha}`;\n}\n\n\/\/ --- main BTT script ---\nasync function itemScript(itemUUID) {\n  try {\n    const cfg = {\n      script: 'OUTPUT_FORMAT=json \/opt\/homebrew\/bin\/chrome-cli info',\n      launchPath: '\/bin\/bash',\n      parameters: '-c'\n    };\n    const raw = await runShellScript(cfg);\n    const data = JSON.parse(raw);\n\n    const id = String(data.id ?? 'unknown');\n    const rgba = stringToBttRgba(id, 0.7);\n\n    const content = {\n      BTTMenuItemBackgroundColor: rgba,\n      BTTMenuItemText: `${id} | ${rgba}`\n    };\n\n    return JSON.stringify(content);\n  } catch (err) {\n    return JSON.stringify({\n      BTTMenuItemText: `err: ${err && err.message ? err.message : String(err)}`\n    });\n  }\n}",
            "BTTScriptFunctionToCall" : "itemScript",
            "BTTScriptLocation" : 0,
            "BTTAppleScriptUsePath" : false,
            "BTTJavaScriptUseIsolatedContext" : false
          },
          "BTTMenuItemBackgroundColor" : "38.364750, 125.776200, 225.675000, 255.000000",
          "BTTMenuTextMinimumScaleFactor" : 0.29999999999999999,
          "BTTMenuScriptAlwaysRunOnFirstLoad" : 1,
          "BTTMenuItemBackgroundType" : 4,
          "BTTMenuItemMaxHeight" : 50,
          "BTTMenuHoverEndAnimationDuration" : 0.14999999999999999,
          "BTTMenuItemMaxWidth" : 200,
          "BTTMenuItemResizeImage" : 3,
          "BTTMenuItemBorderColorHover" : "255.000000, 255.000000, 255.000000, 255.000000",
          "BTTLastChangeUUID" : "44F06733-7A5A-4090-94F8-BBC404530A89",
          "BTTMenuItemBorderColor" : "255.000000, 255.000000, 255.000000, 255.000000",
          "BTTMenuItemMinHeight" : 50,
          "BTTMenuItemVisibleWhileActive" : 1,
          "BTTMenuItemBackgroundColorDark" : "108.442, 96.000, 190.435, 166.991",
          "BTTMenuElementIdentifier" : "no-name-D86A40F",
          "BTTMenuItemVisibleWhileInactive" : 1,
          "BTTMenuItemMinWidth" : 100,
          "BTTMenuItemBackgroundTypeDark" : 4,
          "BTTMenuAttributedText" : "{\\rtf1\\ansi\\ansicpg1252\\cocoartf2865\n\\cocoatextscaling0\\cocoaplatform0{\\fonttbl\\f0\\fnil\\fcharset0 HelveticaNeue;}\n{\\colortbl;\\red255\\green255\\blue255;\\red255\\green255\\blue255;}\n{\\*\\expandedcolortbl;;\\cssrgb\\c100000\\c100000\\c100000;}\n\\deftab720\n\\pard\\pardeftab720\\qc\\partightenfactor0\n\n\\f0\\fs44 \\cf2 \\expnd0\\expndtw0\\kerning0\nNew Item}",
          "BTTMenuItemBorderColorHoverDark" : "255.000000, 255.000000, 255.000000, 255.000000",
          "BTTMenuScriptUpdateInterval" : 1,
          "BTTMenuAppearanceStyle" : 0,
          "BTTMenuItemBackgroundColorHover" : "90, 90.000, 180, 166.991",
          "BTTMenuAlwaysUseLightMode" : 1,
          "BTTMenuScriptAlwaysRunOnAppear" : 1,
          "BTTMenuItemScriptActive" : 1,
          "BTTMenuUseStyleForSubmenu" : 0,
          "BTTMenuItemBackgroundColorHoverDark" : "90, 90.000, 180, 166.991",
          "BTTMenuHoverStartAnimationDuration" : 0.14999999999999999
        },
        "BTTMenuAvailability" : 0,
        "BTTMenuName" : "no-name-D86A40F",
        "BTTGestureNotes" : "Standard Item"
      }
    ],
    "BTTFloatingMenuRenderedPreview" : "iVBORw0KGgoAAAANSUhEUgAAAMgAAAA2CAYAAACCwNb3AAAAAXNSR0IArs4c6QAAAHhlWElmTU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAABIAAAAAQAEJhkAAA77AAOgAQADAAAAAQABAACgAgAEAAAAAQAAAMigAwAEAAAAAQAAADYAAAAAiG8T_gAAAAlwSFlzAAALEwAACucBcYjSlgAAEC5JREFUeAHtXXtwVNUZ_+7dd7J5kJDwMMEgLwEBxRf4QkErtpZWpyq+x2eV6jjVaTvjdEb_asfaaf9obRW12mp9VnTGqh0FRAEBEQFBIQgYYiAkJCHJbrLZx723v9_dbNwkmxBIkLtwTmaz955z7jnf+e73O9_j3HtWkwxp_PgrfIFA81hxW2VWXIpM0YIZqqksxYGs5oAuVljzSJMktJpIpPCbnTvfi_YckNYz49QZF0zUTfN8TcxSyxKX6JolptmzmjpXHMh+Dui6iGlpmiaGJXq9qeurt29etSN9YN0AMnn6rJmaac3Vdc1rWVZGVGiJiGEaiYxl6Q2r48wc0HW3Znl8bhHcHJUcwwGgBHrBilm6tnzbF2s_TxHWBZDJp587QeLaVZpmuYAoK1Wh6zsRNQWIs8ovKrNKp5VZwdGjLG9uQGmXLg71fcCZKt4R08K1tVpT5V69alm1logaltvn6vsiVfJ9cwAWk2ZZmiEe681tm9Z9zf5tgFRUVPgDwdIbXbo+EprD6EmYFosaRvH4fPPMRfOlcOwUcfm9libAUvL6nvXVeQYOcNLBn2V0GBLeu8u98el39f0b6yxPANpEJadwAJrEZRhmXaSt_sWqqqoOewYrL588XtO1czKBQxJx0ywal2+e9_AtMuyUSVAtXhEDqsSkAQeAqc+AeJDkF3jmcms5JcXmyLMmaKHq3frBPSFxeZS95RSEiFi6ruf5vHm19fU1DfaNgbsxBuDIeJPobJgz771C8k4qt8wYgAGI0ABTnyPjAdUI+KjlFJUY0+9cYAYKPHAUyU2VHMIBYoGYIDkEBewuazhUSy_Hm3ayPua80VJ4ynTLimXyTBwypCwjg3OMEdWsvLLxVsVl4yyjvZdZm2UjOq7IJRaICQxKA0Ae1QzdlWfChe85StOImebwGWPEk8NZrmexOh8MB8BOzePVrJKpFQh0KOYOhpdDfC2xQEwQG7ZZBX3SFc3q3pcpVkHZKOWKd+fKkJ1hfcnMHT1Kd3kzmrdD1o9q6LA5kMLEIW+M6cnN6Qx2HXYn6oL+OUC1AS2SS2XSf01Veqw4cEiAwEE5VrSdGP0q9jr6Ph8SII6mXhGnOHCUOaAAcpQZrJrPbg4ogGT3_VPUH2UODBogfGwxgShlX6Y0A5h2eV8VjvIA6UKxfxVIPcqMPk6bH9RzQDpiL+XD3HgiXqS2JcFnhruFYyicwwK65Pl1ORAypAMVvs9wDfvP8WhSHHRLe8yUxja82QIC4qCDgPG6+EDZcXpn1bCGhANHrEEoYHk+XZ67pUSW_HyEXHdWUGJxZKalKM5vODcoS+4ZIbPG+XuVp1U9KoexhCXnjPXb_d93SYHwnBrvrDF+ueqMoBQAvEqzHBXWHzeNHjFAyAHOvhSywhxdFs3Jl0kjvfbsnOIO4eLHDM46nMm7w6f7o0ypa4bym_158Dgm+8_1JvuPAyTXnpkrv__JMBlV4BIjA0J4XU9a+6IrU91MeX1dr_KdzYFBAYRDSwlSaZ5LHrqsAAIJQUxlpo09PYvHnM1ZD9XtRuzzzvo0gfhJb8fAzM88+hPpKVU3PS_TMa9iezG0QTuPwGVbCZ53JjZNOkgS6WKfPE9PNg24hvksZz273c5z5tPk5Id99aQ3vS117HwODMoH4fBcgFhVY0JaI4bMmxSQq0_PlZfWh20BZDnkpFuiMFEQ50_NlQUzcqSs0CX18E+WbuuQNzaG7afD7ru4QIpydfn7R63S2G6KAUGbfYpffjw9RzZ9G5f_oJ4b_bKtuy_Il9Fo44kVrdKEuhTMTImaojTfJTS1Zo7x2VUemFsguw4k5KmPWyUcs8QPaV8IU_GyUwO2VqxuSshbm9tlWWW7eNCwz63J_Rfny4GwKbtx3cKzc6W8yC37Wgx5_bM22bw3KrfOygOtPnuMW_fF5IW1Iak+mAC9fRCWiViV5xgODBogvO+hDlP+sLRFnrx+uNw_N1_WVkVlD0CTKRmQ6gchmLdDsCNRC8ITlzPKfXL+eL+cXOySx95vlimjvDIPQrp6Z4cs3R6xm_nRtBz52cygzCiPyX+_aIPDb8qIPLfcM6cAAEvI4++39AJjev8EE02tuRMDMjyYVJxnlPulNC8hT69qlQCE_7Gri+TSyQGpCxtyECC4dEpA5oKOR97W5fUNYQki2LBgRhDg0QBETRraDGnDi5YE1DkVPtkPoJxc7JGv62IyPE_HuPJkUqlH7nmpQaLQLCogkH5HsuN40CYWh0mzav03UfnnmhDserc8OC_f1iywQLolmhznnxKQOy8skM01UVn4bJ3c9Hy93PSPOvkKs+3t5+fLTIDlva2YseE7zMJMjEskgGf5CCLmnVzkkTLM2gwITIbPUxjQZHllREIQ1P4E0A0aqxrics1T+2UF6jP95s0GufelA9ISMeW6s4Ny+dQceWtTmyx8qk5ufq5e7nrhADSjKb+6vEBOQrSOD93y1Y18AOXtL8Jyw9N1cv2z9fLy+pAUwQ8bCQ216CWMB2O6FdfvaYrL2QgSjLB9nW6sUCdZwoEhAQjHyhfZn1kdli01MbnitFy5clquMIqVnjiLXzkjAFNF5DnUrcWM64ONVn3QkGdXhxB2FVkAM2rdng5phVaaBeGir8BQckWxWz7Z3SEBnE8r88K+FzlvHF5uRPp4R0dvWy69485j+gz7Wg2JdNLVEDKlDuadF9rjpzD3qA2eXxuWdpQT9Bu_jcprn4elNOiSi6Dh4uiTIGyEhvnLhyHZj+9WmHUrdyZ3i6EptmJHxPZPdjckYA5G7TH50X7fK0UZCFVZjuHAoE2s1Ei4L8FBvPfz+NJmWXxjifwSptbHX0e6nFS8gGILe8Uwj33JowuG2U4uLXPCiNqBaeoon9RDiDfsicoFEMrR0EiTRnokB1GoV9e3wWTxyqyTvbJko2aHcKsxS1P7eAdg47OfdE+Aws69W4pzXDC13BJE2PoZ0M6H_1mPux0F_ckrJo4Eq75IOuX0dThW+hUxaBXb8Uf9egAOu8jY17KvjsxWJkpUyhYODBlAOGDOup_Ab_j3upDcAR_jgXkFEoaJkkoUNReAQE2yqTratXBoCyPyOLNTq7B8aWWHXAKnn7b91FHY3QuLfKt2RWRbXa5ML0PeCK9tYr38aUgOQttwlj6SREEmUNwuS9qwmPhpdUcXiJjPKFcMgv7lPjrayR5IXyqx17TTVLb9fWQUdWtCnRxjDgwpQCgQ2PxBFq8KYfYPyDVwqqsa48khQto6AIC9zQk5E1GkZ2BSbQBIKNj0M_Ixe9MR3wU_gQK3FmBoixXID+A0jy50y9Z9UdkPzUJfZxEiSQtOz7EFdhnMqyMVREbTCAJqA2oFrvr_7t1mnJt22wzpVsDpnjMhIFsRocKrmBlvV+bcjFVVZpZxYMh8kNS4oUQQBjXkjx80Q8gsmTQiaVJRiCj4y7fDX0C6F0I+Ak4tdoeyz2+dHZSHf1go00_y2hpkD0Kjn8PMugjCyTbWfROzTbLPqmO2prrurDxEyuKyBXY+NdfhpGSPAgdft007+hzLEC0rhq9x14V5tilIunIB2ocuLZBfzy8Are4uc_Fw+lJ1s5sDg9IgFEuuDdDJTU8UWDqrr2A95GasCzDRReCzTx9sb5d3tvjtdZAld4+ULfAfirHmMQNRql0HEMLd0i5uUJWAWbO8MioXAiBM6+G402HfWR+zneQSLEy+uzUqjTDhfP0AJOWapK9D1EITMf352uFSWRuTX7zaIP9aE0aEzSe3zc63Qbm7Pi5jEaKdUOKRZdvaZT1MLz9sLPaV6MG1TH2wfUbOmPpQPHaZ+udsDvS41QMnlrees+xyCDwfAkzfuYZlXI9+ciXCnxB+PqzIxUD6H7Tnf_v2QZhMcbkc6wx0wMPwIV5BqPTFdYhstcLWp0Sh7kqYWR9W+iSM6BIX9ChwNH+WbArb_gfBlBTBzHQzcECzjMECLtrxDXwP2n5jQ5sUIzw8ZrhHmtE3u6vDWsqiVxrltllB2_k_dbRXWrDO8dcPWxDGDSMiB4BDI67aDdMP6zcpP4TgoH_EPmgecuGUiW1W1sbtfNKfAlGyVP3PFg7gNj6qTzntf3cjZlPUc+sfK9oSN+Y_dYsMnzzdSiRNo24Dw9WcJCkstiuesl06K_HUnkRRh_Z+yptlfW7LmAMTJhfaJwKgUegYhk0XJPt6ChwO0tun8PEzkD21U3UZRUvtTcF2md85wdu0kSbms_+gT7NX1cMwvSJw3AGh5E66KOuU_+R4UN9OzMeHfaSiWMy3t55ER4yUse1eyeUVLbS32v3OHU+IG8xQyREcwH3EvdCbvto6f_ERaxB7JLjrWCDucxaHzNgOOKWDx6lE4aSGISjC+AArdoV0cLCufb2NjO7XU5htBzvVYD_f39X9jgIeMZ+0M6VK+M12WyOWtHTtq9oJDlZEGY2zVH1m2Yn5+DDAm15GQA6UzlRT6ttZHBgcQDCWdIHINLS+ylP59nfqJEMDfRX1lZ+hiYw09nW9nY9__ZZn6ORw62doQmU5kANKrTvwpiiSnMMBBRDn3AtFiQM5oADiwJuiSHIOBxRAnHMvFCUO5MAhAKKLFmlq6iNI6cDhZBdJfHRFi7Y2atZAAtbZNbbjhdr+AYIfbJOWPbV2TPR4GbGTxoGVSyu0r9Y0UwFnJxGnaCEH+gWI5vW4XDUrd0usNSz6oCPCiuPpHOCyfqw9odesrFS7u6czxlnH_QJEdPx+RdO2Zu3bVcvxI6BYHOi_urOG5mRqYFq5faLVfb7a9e0nterHPJ17rw4p8Zon1+3a8LfVUrNmBX7l1uKNTQKlr6Ux5w72mFOGCUbj4yX4SN2mz9yf_ul9y61+n_CY35d+CBiA3UQMWZr+8SPvyoxba8wxF8_W_IWjLJc3R3Mldwfpp31V1MkBy8DTjkYsIpGmA1rNmvWuzYvX4+kUGLk9HoVWHHMUBwYAEN5EGFjegMva+Oxm97bXvrSGTSywCscWW94gENL5sJSjhuU0YnTRE5G4tFQ1ao07mqWjMSa+PLwoc0gF7rSBnHD0DAwgnWzR_Hhxm8+2Nn55UOo3Nmrqt_UGLjA6ZhkN27O4oTF8+GVblbKCAxD4R_E47dkhXXMV83HtQyfMevghaU1XtvOheaVqZCMHKN74Gc8QsZF0MEx3Y_IZ+GwcjqJZcWBoOUAsaMAEWrUBgm+zGqGpgaiPoaVEtaY44EgOEAvERKeX2NYW2G1ZZgOM5M7dqRxJtSJKceCoc4AYIBaICXZGE0uqqlZ0GLr5IZ4IohuiFjjIFJVOOA5Q9okBYoGYIAO6NEZj3b7G0pJybP5kjoOTYvsmJxyH1IBPWA4kNQdf_9aXbtv6KfbQTKZe2mLitNmnIrQ1B1sNlHCBEMlEUv5JimPq+7jhAKNVyeAUvkTDvjny0Y4ta7anD7AXQFg4fvwVPk_OgQliucbAXSmCAx9Mv0gdKw4cHxywwthXo0k0ozreXvL1zp3vJXchTxtcRoCklXceXtNlivUuUzmKA9nKgdeTOwj2Q_7_AU3MwB8G0gYfAAAAAElFTkSuQmCC",
    "BTTMenuConfig" : {
      "BTTMenuItemBorderWidth" : 2,
      "BTTMenuWindowResizable" : 1,
      "BTTMenuFrameWidth" : 220,
      "BTTMenuItemPaddingBottom" : 5,
      "BTTMenuItemsUseModifierModes" : false,
      "BTTMenuFrameHeight" : 300,
      "BTTMenuItemCornerRadius" : 10,
      "BTTMenuWindowLevel" : 3,
      "BTTMenuAlwaysUseLightMode" : 1,
      "BTTMenuElementIdentifier" : "no-name-2F2C39D",
      "BTTMenuItemBorderColorHover" : "0.000, 0.000, 0.000, 0.000",
      "BTTMenuItemShadowEnabled" : 0,
      "BTTMenuItemPaddingRight" : 10,
      "BTTMenuHorizontalSpacing" : 5,
      "BTTMenuItemBackgroundType" : 4,
      "BTTMenuItemPaddingTop" : 5,
      "BTTMenuShowIfWindowLevelEqualsEnabled" : 0,
      "BTTMenuItemBackgroundColor" : "168.213, 183.731, 225.311, 29.612",
      "BTTMenuItemPaddingLeft" : 10,
      "BTTMenuItemBlurredBackground" : 1,
      "BTTMenuCloseAfterAction" : 0,
      "BTTMenuItemBorderColor" : "0.000, 0.000, 0.000, 0.000",
      "BTTMenuOpacityInactive" : 1,
      "BTTMenuTextMinimumScaleFactor" : 0.29999999999999999,
      "BTTMenuVerticalSpacing" : 5,
      "BTTMenuOpacityActive" : 1
    },
    "BTTMenuAvailability" : 0,
    "BTTMenuName" : "no-name-2F2C39D"
  }
]

are you sure the window number is what you want? These are not stable and will change once the window is closed - I believe naming the window should be a better solution.

Note: {variableName} only works well for auto-updating variables, “on demand” variables are not refreshed automatically. However you can either use a script inside of the floating menu to generate /update or you can refresh that variable in some script running outside of the floating menu.

@Worie if you have a crashlog in the macOS console app’s crash report section that would be great!

BetterTouchTool-2025-09-23-151718.ips (88.8 KB)

I have dozens of them so let me know if you need more!

So Chrome inherits tabs titles by default, can you please remind me how can I change a window title? I swear I did it a while ago somehow but can’t find anything on web now to remind myself either. Can’t see an explicit action related to that in BTT, and the issue I have is I would have to somehow tie the custom name to the window, that’s why I thought maybe using a WindowNumber would work.

I don’t mind if they change over time (i.e. when I close them), but I think as long as they’re alive, the number should stay the same right?

Thanks, I will take a look! Overall my reqs would be so I can have a unique color for each window (based on a title at task at hand - custom set manually by me each time), a label equal to that title, and thats pretty much it. I can look into adding more automations upon interactions with the menus later.

Also, is there an easier way to make sure that a floating menu is equal to related window width/height automatically? The fields mention it should be pixels, not percentiles, and it’s hard to make them fit the window as they’re resized with other actions. I’m not sure how does it works internally, but using window size as relative unit is now hard because when I select the variable based configuration:

I cannot specify a max dimension - leading to floating windows expanding outside of focused window if resized with an action.

I’ll post an example preset that allows you to easily “tag” windows with a floating overlay later / maybe tomorrow. Made some changes today that make this much easier.

1 Like

Sorry I completely forgot to finish this.

Here is an example preset (requires v5.73x) that shows how to tag a window:
window-tagging.bttpreset (43.4 KB)

When pressing cmd+opt+ctrl+ T It shows a custom context menu with 3 example tags. When clicked that chosen tag will be attached to the currently active window. This works through the predefined action "Toggle Attach Floating Menu To Active Window".

The 3 example floating menus are defined in a CAG to group them:

1 Like