Trigger different actions on multiple presses of the same shortcut

It would be great if you could setup multiple actions for the same shortcut. For example:

CMD+SHIFT+RIGHT: Maximize to right two thirds
CMD+SHIFT+RIGHT: Maximize to right half
CMD+SHIFT+RIGHT: Maximize to right one third
... cycle to first...

I love to quickly set a window to a certain size of the screen. But now I have to use different shortcuts for every size, if you could cycle through it would be awesome.

Same here. I often use a grid of 3 by 2 windows or 2 by 2 and switching between them is not that easy.

This would be extremely useful for "toggle" actions. For example, a single button that could cycle between ["Show Hidden Files", "Hide Hidden Files"] in Finder. This would make more logical sense than two separate buttons, as repeating the same command does nothing.

You could make a toggle switch with applescript and BTT variables.

So far for me, my toggle switchs are working pretty well over at AquaTiuch

I’m not using a three-function toggle, but here’s how it would look like in pseudocode:

start script

(makes the variable and sets it if it doesn’t exist)
if ThisTriggerState is missing value
set persistent BTT variable “ThisTriggerState” to 1
end if

if state is 1
do named trigger 1
set “ThisTriggerState” to 2
exit

else if state is 2
do named trigger 2
set “ThisTriggerState” to 3
exit

else if state is 3
do named trigger 3
set “ThisTriggerState” to 1
exit

end if
end script

Yes. This would be so useful. I needed this to take my cursor to different monitors using the same command

This hack worked. Thank you so much

Does anyone have an example action for this? I like to do exactly what the topic describes, but I don't really get how to run a trigger based on its name.

I've finally got something working! Took me awhile... for anyone else, make use you make named functions within Named & Other triggers for the functions you want to use. Than select Run Apple Script (async in background). I've than oped for Javascript (the BTT calls it Java Script (which is confusing cause it has nothing to do with Java). I than run the following code

var BetterTouchTool = Application('BetterTouchTool');

if (BetterTouchTool.get_number_variable("alloyCycle") == 3) {

  BetterTouchTool.trigger_named("Right two third");
  BetterTouchTool.set_number_variable("alloyCycle", { to: 2 });

} else if (BetterTouchTool.get_number_variable("alloyCycle") == 2) {

  BetterTouchTool.trigger_named("Right one third");
  BetterTouchTool.set_number_variable("alloyCycle", { to: 1 });


} else if (BetterTouchTool.get_number_variable("alloyCycle") == 1) {

  BetterTouchTool.trigger_named("Right half");
  BetterTouchTool.set_number_variable("alloyCycle", { to: 3 });


} else {

  BetterTouchTool.trigger_named("Right half");
  BetterTouchTool.set_number_variable("alloyCycle", { to: 3 });

}

The only thing that I try to do now is have it always set to half width (because this is what I want most of the time) when the function hasn't ran in some time. I've tried using the setTimeout, but this doesn't seem to work.

setTimeout(() => BetterTouchTool.set_number_variable("alloyCycle", { to: 1 }), 1000);

Hope this helps some one and if you have a solution to have it reset after the function hasn't ran in some time, let me know.

Just want to bump this as I came to this page looking for the same thing. It would be incredibly useful to have a series of different triggers that would be performed if the same shortcut was executed within a threshold time (e.g. tapping shortcut once then again within 1 second). After the threshold time expired then the "state" of the sequence would automatically be reset to the initial action. Another option would be to simply cycle the sequence once it gets to the end.

Based on @mvaneijgen script I created one which resets the cycle after a two second timeout :slight_smile:
I changed it to "Real Javascript", as this is recommended by BTT. Just make sure you select "Source Type: Real JavaScript" in the Action Configuration.

Use this for the left side window placement:

(async ()=> {

// action definitions
const actionPlaceLeftHalf = {
    "BTTPredefinedActionType" : 19,
    "BTTPredefinedActionName" : "Maximize Window Left",
  };

const actionPlaceLeftTwoThirds = {
    "BTTPredefinedActionType" : 174,
    "BTTPredefinedActionName" : "Resize window to Left Two Thirds",
  };
  
const actionPlaceLeftThird = {
    "BTTPredefinedActionType" : 108,
    "BTTPredefinedActionName" : "Resize window to Left Third",
  };
  
// system variables
let result = 'error happened!';
const lastTriggeredTime = await callBTT('get_number_variable', {variable_name:'PlaceLeftCycleLastTriggerTime'})

// reset, if trigger was pressed 2 seconds ago
if (lastTriggeredTime + 2000 < Date.now()){
   await callBTT('set_number_variable', {variable_name:'placeLeftCycle', to: 1});
}

const alloyCycle = await callBTT('get_number_variable', {variable_name:'placeLeftCycle'});

// cycling on repeated press
if (alloyCycle == 1) {

  result = await callBTT('trigger_action', {json: JSON.stringify(actionPlaceLeftHalf)});
  result = await callBTT('set_number_variable', {variable_name:'placeLeftCycle', to: 2});

} else if (alloyCycle == 2) {

  result = await callBTT('trigger_action', {json: JSON.stringify(actionPlaceLeftTwoThirds)});
  result = await callBTT('set_number_variable', {variable_name:'placeLeftCycle', to: 3});


} else if (alloyCycle == 3) {

  result = await callBTT('trigger_action', {json: JSON.stringify(actionPlaceLeftThird)});
  result = await callBTT('set_number_variable', {variable_name:'placeLeftCycle', to: 1});

} else {
  result = await callBTT('trigger_action', {json: JSON.stringify(actionPlaceLeftHalf)});
  result = await callBTT('set_number_variable', {variable_name:'placeLeftCycle', to: 1}); 
}

callBTT('set_number_variable', {variable_name:'PlaceLeftCycleLastTriggerTime', to: Date.now()})

returnToBTT(result);

})();

and this for the right side:

(async ()=> {

// action definitions
  
const actionPlaceRightHalf = {
    "BTTPredefinedActionType" : 20,
    "BTTPredefinedActionName" : "Maximize Window Right",
  };
  
const actionPlaceRightThird = {
    "BTTPredefinedActionType" : 110,
    "BTTPredefinedActionName" : "Resize window to Right Third",
  };

const actionPlaceRightTwoThirds = {
    "BTTPredefinedActionType" : 175,
    "BTTPredefinedActionName" : "Resize window to Right Two Thirds",
  };
  

// system variables
let result = 'error happened!';
const lastTriggeredTime = await callBTT('get_number_variable', {variable_name:'PlaceRightCycleLastTriggerTime'})

// reset, if trigger was pressed 2 seconds ago
if (lastTriggeredTime + 2000 < Date.now()){
   await callBTT('set_number_variable', {variable_name:'placeRightCycle', to: 1});
}

const alloyCycle = await callBTT('get_number_variable', {variable_name:'placeRightCycle'});

// cycling on repeated press
if (alloyCycle == 1) {

  result = await callBTT('trigger_action', {json: JSON.stringify(actionPlaceRightHalf)});
  result = await callBTT('set_number_variable', {variable_name:'placeRightCycle', to: 2});

} else if (alloyCycle == 2) {

  result = await callBTT('trigger_action', {json: JSON.stringify(actionPlaceRightTwoThirds)});
  result = await callBTT('set_number_variable', {variable_name:'placeRightCycle', to: 3});


} else if (alloyCycle == 3) {

  result = await callBTT('trigger_action', {json: JSON.stringify(actionPlaceRightThird)});
  result = await callBTT('set_number_variable', {variable_name:'placeRightCycle', to: 1});

} else {
  result = await callBTT('trigger_action', {json: JSON.stringify(actionPlaceRightHalf)});
  result = await callBTT('set_number_variable', {variable_name:'placeRightCycle', to: 1}); 
}

callBTT('set_number_variable', {variable_name:'PlaceRightCycleLastTriggerTime', to: Date.now()})

returnToBTT(result);

})();
2 Likes