No internet connection
  1. Home
  2. How to

How to change Decks on Stream Deck based on modifier keys held

By N Leyers @NickLeyers_old_acc
    2019-10-22 15:09:54.427Z

    I think it can be handy to have a layered SD-page when you press a modifier like ctrl.
    For example: the icon shows 'declick' in iZotope. When you press it, it shows the declick-window.
    When you press it while holding ctrl, it renders 'declick'.

    Practically, I think it will just show a new page with other commands when you press the modifier. So you can assign anything you want. The way the keyboardmap in SF works.
    This will save me some foldermaking and unnessecairy pressing buttons to navigate in SD.

    I know about
    if (event.keyboardState.hasShift) ...
    but I think it has to be done in the deck-designer, otherwise it will affect all the scripts I've made.

    Thoughts?

    • 5 replies
    1. I know about
      if (event.keyboardState.hasShift) ...
      but I think it has to be done in the deck-designer, otherwise it will affect all the scripts I've made.

      Do you mean that you'd have to change all your scripts?

      --

      One way to work around this today would be to:

      • Have a script running continuously that checks for keyboard states and upon changes in those states, changes the stream deck. You could implement this today :)
        You would probably just want one single script per Deck that controls that Deck. So you'd get rid of any Application Triggers on Decks, and then have a script controlling the Deck instead.
      1. NN Leyers @NickLeyers_old_acc
          2019-10-25 12:48:15.209Z

          Hmm... So if I launch the SD, the trigger to open the deck should also launch a script to check if ctrl is pressed? The' checker' will be a seperate script then? I'm missing some skills for programming that I'm affraid. No rush, but could be handy one day.

          1. You can use this as a start:

            • Remove all application triggers that start decks on the Stream Deck that you want to control.
            • This script is now in charge of showing decks on your first Stream Deck device.
            • In the "Deck IDs" section you need to paste in Deck IDs for the decks that you want displayed
            • Right now deck1 will be shown by default, and deck2 will be shown when the "ctrl" modifier is held.
            • To get the Deck IDs, select the Deck in the editor page, choose Cmd+C, then in the script editor, choose Cmd+V.
            • To stop the script (for example if you've changed something and want to run a new version) use the Ctrl+Shift+Esc to stop all running commands.

            Once you've figured out that this script works well for you, you could add a Finder application trigger to it so that it will always be started when Finder is in focus (it will take care of itself to not be running more than one simultaneously).

            /* CONFIG */
            
            //Select the Stream Deck device you want to control
            var device = sf.devices.streamDeck.firstDevice;
            
            //Deck IDs
            var deck1 = 'user:cjy7orsth0001km10gr3cte4g:cjy7osmp60002km10pca66ryj';
            var deck2 = 'user:cjy7orsth0001km10gr3cte4g:cjy8fnbdz0000xx10r6fow63c';
            
            /* SCRIPT */
            var lastKeyboardState;
            
            function main() {
                var keyboardState = event.keyboardState.asString;
                if (keyboardState !== lastKeyboardState) {
                    lastKeyboardState = keyboardState;
            
            
                    switch (keyboardState) {
                        case 'ctrl':
                            sf.decks.get(deck2).showOnStreamDeck({ device: device });
                            break;
            
                        case '':
                        default:
                            sf.decks.get(deck1).showOnStreamDeck({ device: device });
            
                            break;
                    }
                }
            }
            
            function runForever(name, action, interval, timeout) {
                var now = (new Date).valueOf();
                if (now - globalState[name] < timeout) throw 0; //Exit if we were invoked again inside the timeout
            
                globalState[name] = now;
                sf.engine.runInBackground(function () {
                    try {
                        while (true) {
                            sf.engine.checkForCancellation();
                            globalState[name] = (new Date).valueOf();
            
                            action();
            
                            sf.wait({ intervalMs: interval, executionMode: 'Background' });
                        }
                    } finally {
                        globalState[name] = null;
                    }
                });
            }
            
            runForever("streamDeckChanger", main, 200, 5000);
            
            1. NN Leyers @NickLeyers_old_acc
                2019-10-25 14:45:59.871Z

                Wow, brilliant, works perfect. My SD's just became super powerfull ;-)

                The only downside is that it overwrites all the other triggered decks. Is there a function to cancel a specific running script?
                sf.soundflow.stopAll(); works, but it will show an error-message every time I use it (that's normal).
                I'll let RX trigger the run-script, while PT triggers the stop-script for now.

                Thanks a lot!!

                1. Yay :)

                  Yea I would augment this to also handle application changes so you remove all your application triggers (for example that for the Stream Deck).

                  This would be a way to do it (pseudo code):

                  /* SCRIPT */
                  var lastAppKeyboardState;
                  
                  function main() {
                      var appKeyboardState = sf.ui.frontmostApp.activeBundleID + '::' + event.keyboardState.asString;
                  
                      if (appKeyboardState !== lastAppKeyboardState) {
                          lastAppKeyboardState = appKeyboardState;
                  
                          switch (appKeyboardState) {
                              case 'com.avid.ProTools::ctrl':
                                  sf.decks.get(deck2).showOnStreamDeck({ device: device });
                                  break;
                  
                              case 'theizotopeappbundleididontremember::':
                                  //show the izotope deck
                                  break;
                  
                              case 'com.avid.ProTools::':
                              case 'com.apple.Finder::':
                              default:
                                  sf.decks.get(deck1).showOnStreamDeck({ device: device });
                  
                                  break;
                          }
                      }
                  }