Combo Functions

Combos are timed script blocks. Use them for accessibility sequences, device tests, input timing, or other short actions that should run independently from the main block.

combo_name is the combo identifier, not a string.

Quick Reference

Function Signature Returns Use
combo_run int combo_run(combo_name) 1 on success Start a combo or keep it running
combo_restart int combo_restart(combo_name) 1 on success Start a combo again from the first statement
combo_pause int combo_pause(combo_name) 1 on success Pause a running combo at its current position
combo_suspend int combo_suspend(combo_name) 1 on success Alias for combo_pause()
combo_resume int combo_resume(combo_name) 1 on success Resume a paused combo
combo_stop int combo_stop(combo_name) 1 on success Stop a combo immediately
combo_running int combo_running(combo_name) 1 while running Check whether a combo is active
combo_suspended int combo_suspended(combo_name) 1 while paused Check whether a combo is paused
combo_stop_all int combo_stop_all() Status value Stop every combo
combo_suspend_all int combo_suspend_all() Status value Pause every running combo
combo_resume_all int combo_resume_all() Status value Resume every paused combo
call call(combo_name) N/A Run another combo from inside a combo and wait for it
wait int wait(int ms) 1 on success Delay combo execution

Basic Combo Pattern

gpc
main {
    if (event_active(BUTTON_11)) {
        combo_restart(OutputTest);
    }
}

combo OutputTest {
    set_val(BUTTON_15, 100);
    wait(100);
    set_val(BUTTON_15, 0);
}

combo_run

gpc
int combo_run(combo_name);

Starts a combo if it is stopped. If the combo is already running, combo_run() keeps it running without restarting from the first line.

gpc
main {
    if (event_active(BUTTON_11)) {
        combo_run(OutputTest);
    }
}

combo OutputTest {
    set_val(BUTTON_15, 100);
    wait(250);
    set_val(BUTTON_15, 0);
    wait(100);
}

Use combo_restart() when you need to force the combo back to the beginning.

combo_restart

gpc
int combo_restart(combo_name);

Starts the combo from the first statement, even if it is already running.

gpc
main {
    if (event_active(BUTTON_11)) {
        combo_restart(QuickTap);
    }
}

combo QuickTap {
    set_val(BUTTON_15, 100);
    wait(60);
    set_val(BUTTON_15, 0);
    wait(60);
}

Pause, Suspend, and Resume

gpc
int combo_pause(combo_name);
int combo_suspend(combo_name);
int combo_resume(combo_name);

Pauses and resumes a combo without losing its current position. combo_suspend() is an alias for combo_pause().

gpc
main {
    if (event_active(BUTTON_4)) {
        if (combo_suspended(LongSequence)) {
            combo_resume(LongSequence);
        } else if (combo_running(LongSequence)) {
            combo_pause(LongSequence);
        } else {
            combo_run(LongSequence);
        }
    }
}

combo LongSequence {
    set_val(BUTTON_15, 100);
    wait(2000);
    set_val(BUTTON_15, 0);
    wait(100);
}

combo_stop

gpc
int combo_stop(combo_name);

Stops the combo immediately. The next combo_run() starts from the beginning.

gpc
main {
    if (event_release(BUTTON_10)) {
        combo_stop(LongSequence);
    }
}

combo LongSequence {
    set_val(BUTTON_15, 100);
    wait(2000);
    set_val(BUTTON_15, 0);
    wait(100);
}

Use combo_stop() when the condition that started the combo is no longer true.

Running and Suspended Checks

gpc
int combo_running(combo_name);
int combo_suspended(combo_name);

Use state checks when one feature should not interrupt another, or when a button toggles a combo state.

gpc
main {
    if (event_active(BUTTON_12)) {
        if (combo_running(DiagnosticSequence)) {
            combo_stop(DiagnosticSequence);
        } else {
            combo_run(DiagnosticSequence);
        }
    }
}

combo DiagnosticSequence {
    set_val(BUTTON_15, 100);
    wait(250);
    set_val(BUTTON_15, 0);
    wait(100);
}

call

gpc
call(combo_name);

Calls another combo from inside a combo and waits for it to finish before continuing. Use it to compose reusable combo steps.

gpc
combo TapBottomFace {
    set_val(BUTTON_16, 100);
    wait(60);
    set_val(BUTTON_16, 0);
    wait(60);
}

combo DoubleTapBottomFace {
    call(TapBottomFace);
    call(TapBottomFace);
}

call() belongs inside a combo block. Treat it as combo sequencing syntax, not as a normal value-returning function.

wait

gpc
int wait(int ms);

Delays combo execution for a number of milliseconds. wait() is what makes combos useful for timed sequences.

gpc
combo TimedPress {
    set_val(BUTTON_16, 100);
    wait(70);
    set_val(BUTTON_16, 0);
    wait(70);
}

wait() belongs inside a combo block, not in main.

All-Combo Controls

gpc
combo_stop_all();
combo_suspend_all();
combo_resume_all();

Use these when a global mode change should affect every active combo at once.

Practical Patterns

One-Shot Sequence

gpc
main {
    if (event_active(BUTTON_5)) {
        combo_restart(OneShot);
    }
}

combo OneShot {
    set_val(BUTTON_16, 100);
    wait(80);
    set_val(BUTTON_16, 0);
    wait(60);
    set_val(BUTTON_13, 100);
    wait(80);
    set_val(BUTTON_13, 0);
}

Mode-Dependent Combo

gpc
bool extended_test = FALSE;

main {
    if (event_active(BUTTON_11)) {
        extended_test = !extended_test;
    }

    if (event_active(BUTTON_5)) {
        if (extended_test) {
            combo_restart(LongOutputTest);
        } else {
            combo_restart(ShortOutputTest);
        }
    }
}

combo ShortOutputTest {
    set_val(BUTTON_15, 100);
    wait(75);
    set_val(BUTTON_15, 0);
}

combo LongOutputTest {
    set_val(BUTTON_15, 100);
    wait(250);
    set_val(BUTTON_15, 0);
}

Notes

  • Keep combos focused. One combo should usually do one timed action.
  • A combo stops when it reaches the end. For continuous behavior, let main call combo_run() again while the trigger condition remains true.
  • Use combo_run() for repeated behavior and combo_restart() for one-shot retriggers.
  • Stop combos when their activation condition is no longer true.
  • Do not put long loops or blocking timing logic in main; use combos for timed output.