{"record":{"id":"6212a78f8b0b6cc9","repo":"tonhowtf/omniget","slug":"ja-esta-rodando","errorCode":null,"errorMessage":"ja esta rodando","messagePattern":"ja esta rodando","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"src-tauri/omniget-core/src/core/tools/autoclick.rs","lineNumber":103,"sourceCode":"        if left > Duration::from_micros(1500) {\n            std::thread::sleep(left - Duration::from_micros(1200));\n        } else {\n            std::hint::spin_loop();\n        }\n    }\n}\n\nfn button_of(name: &str) -> Button {\n    match name {\n        \"right\" => Button::Right,\n        \"middle\" => Button::Middle,\n        _ => Button::Left,\n    }\n}\n\npub fn start(opts: ClickOptions) -> anyhow::Result<()> {\n    if RUNNING.swap(true, Ordering::SeqCst) {\n        return Err(anyhow!(\"ja esta rodando\"));\n    }\n    if !(0.1..=1000.0).contains(&opts.cps) {\n        RUNNING.store(false, Ordering::SeqCst);\n        return Err(anyhow!(\"CPS fora de 0,1 a 1000\"));\n    }\n    *LAST_OPTS.lock().unwrap_or_else(|e| e.into_inner()) = Some(opts.clone());\n    *ERROR.lock().unwrap_or_else(|e| e.into_inner()) = None;\n    CLICKS.store(0, Ordering::SeqCst);\n    *STARTED.lock().unwrap_or_else(|e| e.into_inner()) = Some(Instant::now());\n\n    std::thread::Builder::new()\n        .name(\"omniget-autoclick\".into())\n        .spawn(move || {\n            let mut enigo = match Enigo::new(&Settings::default()) {\n                Ok(e) => e,\n                Err(e) => {\n                    *ERROR.lock().unwrap_or_else(|e| e.into_inner()) = Some(format!(\"nao consegui controlar o mouse: {} (macOS: Ajustes → Privacidade → Acessibilidade)\", e));\n                    RUNNING.store(false, Ordering::SeqCst);","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/autoclick.rs#L85-L121","documentation":"start() refuses to run the autoclicker when it is already active. It atomically swaps the RUNNING flag to true first; if the previous value was already true, another instance is running, so it returns this error instead of spawning a second clicking thread.","triggerScenarios":"Calling start() (directly or via toggle()) while RUNNING is true — i.e. the autoclicker thread from a previous start() is still alive and hasn't finished/stopped.","commonSituations":"User clicks Start twice; a global hotkey toggle races with the UI Start button; a previous run's thread is still winding down (e.g. sleeping between clicks) when start() is called again.","solutions":["Call stop() (or check RUNNING) before starting again, or use toggle() which handles the running case.","Catch this error in the UI and treat it as a no-op/status refresh rather than a failure.","Fix any code path that calls start() while holding a stale RUNNING=true (e.g. after a thread panicked without resetting the flag).","Expose RUNNING state to the UI so the Start control is disabled while active."],"exampleFix":"// before\nif RUNNING.load(Ordering::SeqCst) { stop(); }\nstart(opts)?;\n// after\nif RUNNING.load(Ordering::SeqCst) {\n    stop(); // já está rodando: apenas interrompe\n} else {\n    start(opts)?;\n}","handlingStrategy":"type-guard","validationCode":"fn can_start() -> bool { !RUNNING.load(Ordering::SeqCst) }","typeGuard":"fn autoclicker_idle() -> bool { !RUNNING.load(Ordering::SeqCst) }","tryCatchPattern":"match autoclick::start(opts) {\n    Ok(()) => set_ui_running(true),\n    Err(e) if e.to_string() == \"ja esta rodando\" => { /* já ativo: apenas sincronizar UI */ }\n    Err(e) => show_error(e),\n}","preventionTips":["Use toggle() instead of raw start() for hotkeys/UI toggles.","Disable the Start button while RUNNING is true.","Always stop() before start() in scripts.","Ensure error/panic paths reset RUNNING so the flag never sticks true."],"tags":["rust","autoclicker","state-machine","concurrency"],"backgroundTag":"invalid-state-transition","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}