Handle incomplete sets gracefully in set-based mode
When users have odd numbers of wheel functions (e.g., 3 or 5), the previous code would wrap around unexpectedly when toggling to a non-existent function, causing confusing jumps between sets. Example problem: - 3 functions (Set 1: 0-1, Set 2: 2 only) - At Set 2, function 2, single-click tried to go to function 3 - Function 3 doesn't exist → wrapped to function 0 (jumped to Set 1!) Solution: - Check if target function exists before toggling - If target doesn't exist, stay at current function (no action) - Show debug message explaining why action was ignored Checks added: 1. Single-click: Verify target function exists before toggling within set 2. Double-click: Verify target set's first function exists before switching 3. Triple-click: Double-check target set exists (in addition to >= 5 check) Now works correctly with any number of functions: - 2 functions: Set 1 complete - 3 functions: Set 1 complete, Set 2 has only function 2 (toggle ignored) - 4 functions: Sets 1-2 complete - 5 functions: Sets 1-2 complete, Set 3 has only function 4 (toggle ignored) - 6 functions: All sets complete Files modified: - src/device.c: Add existence checks for all set operations
+40 −13 · 1 file changed
-
src/device.c+40 −13
@@ -324,29 +324,56 @@ void device_run(libusb_context* ctx, config_t* config, int debug, int accept, in // Process based on click count if (final_click_count == 1) { // Single-click: toggle within current set - wheel_position_in_set = 1 - wheel_position_in_set; + int new_position = 1 - wheel_position_in_set; + int target_function = (wheel_current_set * 2) + new_position; + + // Only toggle if the target function exists + if (target_function < config->totalWheels) { + wheel_position_in_set = new_position; + } else { + if (debug == 1) { + printf("Toggle ignored: function %d doesn't exist (have %d functions)\n", + target_function, config->totalWheels); + } + } } else if (final_click_count == 2) { - // Double-click: toggle between Set 0 and Set 1 + // Double-click: toggle between Set 0 and Set 1 (only if target set exists) + int target_set = -1; if (wheel_current_set == 0) { - wheel_current_set = 1; + target_set = 1; } else if (wheel_current_set == 1) { - wheel_current_set = 0; + target_set = 0; } else { // From Set 2, go to Set 0 - wheel_current_set = 0; + target_set = 0; + } + + // Check if target set has at least the first function + int target_function = target_set * 2; + if (target_function < config->totalWheels) { + wheel_current_set = target_set; + wheel_position_in_set = 0; // Start at first function in new set + } else { + if (debug == 1) { + printf("Double-click ignored: Set %d doesn't exist (have %d functions)\n", + target_set + 1, config->totalWheels); + } } - wheel_position_in_set = 0; // Start at first function in new set } else if (final_click_count >= 3) { - // Triple-click: toggle to/from Set 2 (only if Set 2 exists - need at least 5 functions) + // Triple-click: toggle to/from Set 3 (only if Set 3 exists - need at least 5 functions) if (config->totalWheels >= 5) { - if (wheel_current_set == 2) { - // From Set 2, go back to Set 0 - wheel_current_set = 0; + int target_set = (wheel_current_set == 2) ? 0 : 2; + int target_function = target_set * 2; + + // Double-check that target function exists + if (target_function < config->totalWheels) { + wheel_current_set = target_set; + wheel_position_in_set = 0; // Start at first function in new set } else { - // From Set 0 or 1, go to Set 2 - wheel_current_set = 2; + if (debug == 1) { + printf("Triple-click ignored: Set %d doesn't exist\n", target_set + 1); + } } - wheel_position_in_set = 0; // Start at first function in new set } else { if (debug == 1) { printf("Triple-click ignored: Set 3 requires at least 5 wheel functions (have %d)\n",