Added Features#11
Conversation
…lay), and multiple key presses.
|
Ready to act? Review this PR in Change Stack to turn feedback into patch suggestions you can inspect and refine. WalkthroughThis PR refactors XKeyClicker from a single-key repeat mode to a multi-key automation system. A new ChangesMulti-key automation refactor
Sequence DiagramsequenceDiagram
participant User
participant GTK as GTK UI
participant AutoClicker as auto_clicker loop
participant OnStart
participant ClickNextKey
participant OnStop
participant XKeyClicker
User->>GTK: click manual start button
GTK->>XKeyClicker: set active = true
AutoClicker->>AutoClicker: detect state change
AutoClicker->>OnStart: call on_start()
OnStart->>XKeyClicker: apply start_delay sleep
OnStart->>XKeyClicker: simulate press for held keys
loop for each repeat cycle
AutoClicker->>ClickNextKey: should click next key?
ClickNextKey->>XKeyClicker: check current_count vs repeat_count
alt repeat not exhausted
ClickNextKey-->>AutoClicker: return true
AutoClicker->>XKeyClicker: simulate press/release for click key
AutoClicker->>XKeyClicker: increment click_index
else repeat done
ClickNextKey-->>AutoClicker: return false
end
end
User->>GTK: click manual start button to deactivate
GTK->>XKeyClicker: set active = false
AutoClicker->>OnStop: call on_stop()
OnStop->>XKeyClicker: release held keys
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
src/xkeyclicker.ui (2)
296-301: ⚡ Quick winUse numeric widgets for the numeric-only option fields.
src/main.rs:182-213immediately parses both values asu64and rewrites invalid edits back to"0". Keeping these as plainGtkEntrys makes the UI accept states the backend immediately rejects.GtkSpinButtonwould keep the widget contract aligned with the handler logic and avoid the reset-on-parse-failure UX.Also applies to: 340-345
54-57: ⚡ Quick winNormalize the top-level packing positions.
This row is assigned
position=0, but the existing sibling frames still occupy positions0,1, and2. That makes the final ordering depend on GTK's duplicate-position reordering behavior instead of the XML order. Please renumber or remove the explicit positions so the status row placement stays deterministic across future UI edits.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 1bd69a90-9240-499b-b1d1-575e71d630df
📒 Files selected for processing (3)
src/main.rssrc/primitives.rssrc/xkeyclicker.ui
1. Fixed blocking sleeps (src/main.rs:48-66) Added interruptible_sleep() function that checks state every 100ms during delays. This ensures the user can stop during: - Start delay (on_start) - Click cooldown intervals (auto_clicker) 2. Empty numeric fields treated as zero (src/main.rs:230-244, 258-269) Added handling for empty strings in start_delay_entry and repeat_count_entry to explicitly set values to 0 when the field is cleared. 3. Fixed Entry channel/should_recv race condition (src/main.rs:274-337, 465-476) - Replaced the mpsc channel approach with a single shared PendingEntry (Rc<RefCell<Option<Entry>>>) - Both the KeyType and Entry reference are now stored atomically, preventing mismatch when user clicks multiple buttons quickly 4. Dispatch Entry::set_text to GTK main thread (src/main.rs:187-197, 381-414, 478-502) - Replaced direct Entry updates from the rdev listener thread with a glib channel (glib::MainContext::channel) - The listener thread now sends KeyMessage::KeyCaptured to the GTK main thread - The main thread handler processes these messages and safely updates the Entry widgets Other cleanups - Removed unused SendBox type from primitives.rs - Added PartialEq derive to KeyType for comparison - Removed Debug derive from XKeyClicker (Entry doesn't implement Debug)
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main.rs (1)
206-213:⚠️ Potential issue | 🟠 Major | ⚡ Quick winTreat cleared interval fields as zero.
Clearing a cooldown field leaves the previous component in
cooldown, so deleting the default100ms value still runs with a hidden extra100msuntil the user types another number. That makes the new interval controls report one value in the UI and use another in the worker thread.💡 Suggested fix
$time_type.connect_changed(move |entry| { - if let Ok(cooldown) = entry.buffer().text().parse::<u64>() { + let text = entry.buffer().text(); + if text.is_empty() { + xkc_handle_clone.cooldown.lock().unwrap().$time_type = 0; + } else if let Ok(cooldown) = text.parse::<u64>() { xkc_handle_clone.cooldown.lock().unwrap().$time_type = cooldown; - } else if !entry.buffer().text().is_empty() { + } else { entry.set_text("0"); xkc_handle_clone.cooldown.lock().unwrap().$time_type = 0; } });
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4f25d03d-a1d6-457a-867d-91e731ea9ee2
📒 Files selected for processing (2)
src/main.rssrc/primitives.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- src/primitives.rs
Added: Start Delay, Repeat Count, Manual Start (for use with Start Delay), multiple key presses, also inactive/active button.