Variable behavior is not consistent when using the same variable name for different permutations of set_string_variable, set_number_variable, and their persistent variations. It is easiest to show this via JXA (use the Replies view to see results from checkVariables). Be warned that this script will pollute BTT with 12 new variables. I did my best to label each case, so check sections with // Actual:
(tests 5, 8, 9, 10, 11).
ObjC.import('Foundation');
var btt = Application('BetterTouchTool');
// Helper function to display variable values with error handling
// Use `Replies` view in Script Editor to see all values
function checkVariables(varName) {
try {
btt.get_string_variable(varName);
} catch (e) {
e;
}
try {
btt.get_number_variable(varName);
} catch (e) {
e;
}
console.log("");
}
var varName1 = $.NSUUID.UUID.UUIDString.js;
btt.set_string_variable(varName1, { to: "Temporary String" });
btt.set_number_variable(varName1, { to: 42 });
checkVariables(varName1);
// Expected: String null, number returns
var varName2 = $.NSUUID.UUID.UUIDString.js;
btt.set_number_variable(varName2, { to: 42 });
btt.set_string_variable(varName2, { to: "Temporary String" });
checkVariables(varName2);
// Expected: String returns, number null
var varName3 = $.NSUUID.UUID.UUIDString.js;
btt.set_string_variable(varName3, { to: "Temporary String" });
btt.set_persistent_string_variable(varName3, { to: "Persistent String" });
checkVariables(varName3);
// Expected: String returns, number null
var varName4 = $.NSUUID.UUID.UUIDString.js;
btt.set_persistent_string_variable(varName4, { to: "Persistent String" });
btt.set_string_variable(varName4, { to: "Temporary String" });
checkVariables(varName4);
// Expected: String returns, number null
var varName5 = $.NSUUID.UUID.UUIDString.js;
btt.set_string_variable(varName5, { to: "Temporary String" });
btt.set_persistent_number_variable(varName5, { to: 99 });
checkVariables(varName5);
// Expected: String null, number returns
// Actual: String throws Error -1708: Message not understood, number returns
var varName6 = $.NSUUID.UUID.UUIDString.js;
btt.set_persistent_number_variable(varName6, { to: 99 });
btt.set_string_variable(varName6, { to: "Temporary String" });
checkVariables(varName6);
// Expected: String returns, number null
var varName7 = $.NSUUID.UUID.UUIDString.js;
btt.set_number_variable(varName7, { to: 42 });
btt.set_persistent_string_variable(varName7, { to: "Persistent String" });
checkVariables(varName7);
// Expected: String returns, number null
var varName8 = $.NSUUID.UUID.UUIDString.js;
btt.set_persistent_string_variable(varName8, { to: "Persistent String" });
btt.set_number_variable(varName8, { to: 42 });
checkVariables(varName8);
// Expected: String null, number returns
// Actual: String returns "Persistent String", number returns 42
var varName9 = $.NSUUID.UUID.UUIDString.js;
btt.set_number_variable(varName9, { to: 13 });
btt.set_persistent_number_variable(varName9, { to: 75 });
checkVariables(varName9);
// Expected: String null, number returns
// Actual: String throws Error -1708: Message not understood, number returns
var varName10 = $.NSUUID.UUID.UUIDString.js;
btt.set_persistent_number_variable(varName10, { to: 75 });
btt.set_number_variable(varName10, { to: 13 });
checkVariables(varName10);
// Expected: String null, number returns
// Actual: String throws Error -1708: Message not understood, number returns
var varName11 = $.NSUUID.UUID.UUIDString.js;
btt.set_persistent_string_variable(varName11, { to: "Persistent String" });
btt.set_persistent_number_variable(varName11, { to: 99 });
checkVariables(varName11);
// Expected: String null, number returns
// Actual: String throws Error -1708: Message not understood, number returns
var varName12 = $.NSUUID.UUID.UUIDString.js;
btt.set_persistent_number_variable(varName12, { to: 99 });
btt.set_persistent_string_variable(varName12, { to: "Persistent String" });
checkVariables(varName12);
// Expected: String returns, number null
My expectation was that get_string_variable and get_number_variable would not throw errors and would either return a value (when the last value set matched the same type) or null (when the last value set did not match the type). However, get_string_variable is throwing errors after set_persistent_number_variable is called, but not set_number_variable (5, 9, 10, 11) (10 shows that set_number_variable after a set_persistent_number_variable still throws errors).
Test 8 is what prompted me to start debugging these calls - setting a persistent string variable and then setting a temporary number variable ends up seemingly with two variables with the same name:
var varName8 = $.NSUUID.UUID.UUIDString.js;
btt.set_persistent_string_variable(varName8, { to: "Persistent String" });
btt.set_number_variable(varName8, { to: 42 });
checkVariables(varName8);
// Expected: String null, number returns
// Actual: String returns, number returns
Device information:
- Type of Mac: MacBook Pro M3
- macOS version: macOS Sequoia Version 15.3.1
- BetterTouchTool version: 5.199 (SetApp)