Voici un userscript qui ajoute un verrou commutable sur le compositeur.
Il désactive également les raccourcis clavier et fonctionne également sur mobile.

https://greasyfork.org/en/scripts/566254-discourse-composer-safety-lock
Ajoutez ou supprimez des lignes @match pour l’activer sur les forums que vous utilisez.
// ==UserScript==
// @name Discourse Composer Safety Lock
// @namespace https://meta.discourse.org
// @version 2.0
// @description Verrou commutable sur le compositeur pour empêcher la soumission accidentelle de messages
// @author Canapin & AI
// @match https://meta.discourse.org/*
// @grant none
// @license MIT
// ==/UserScript==
(function () {
"use strict";
let locked = false;
// Écouteur en phase de capture sur #reply-control pour bloquer Ctrl/Cmd/Alt+Entrée
function attachBlocker(replyControl) {
if (replyControl._safetyLockAttached) return;
replyControl._safetyLockAttached = true;
replyControl.addEventListener(
"keydown",
function (e) {
if (!locked) return;
if (e.key === "Enter" && (e.ctrlKey || e.metaKey || e.altKey)) {
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
}
},
true
);
}
function updateButtons() {
const rc = document.getElementById("reply-control");
if (!rc) return;
rc.querySelectorAll(".save-or-cancel .btn-primary").forEach((btn) => {
if (locked) {
btn.style.pointerEvents = "none";
btn.style.filter = "grayscale(1) opacity(0.4)";
btn.setAttribute("tabindex", "-1");
} else {
btn.style.pointerEvents = "";
btn.style.filter = "";
btn.removeAttribute("tabindex");
}
});
}
// Bloqueur de clic en phase de capture sur le bouton d'enregistrement
document.addEventListener(
"click",
function (e) {
if (!locked) return;
if (e.target.closest(".save-or-cancel .btn-primary")) {
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
}
},
true
);
// Bloqueur de touche en phase de capture pour Entrée sur le bouton d'enregistrement focalisé
document.addEventListener(
"keydown",
function (e) {
if (!locked) return;
if (
e.key === "Enter" &&
e.target.closest(".save-or-cancel .btn-primary")
) {
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
}
},
true
);
function injectPadlock() {
if (document.getElementById("composer-lock-btn")) return;
const title = document.querySelector(".composer-action-title");
if (!title) return;
const btn = document.createElement("span");
btn.id = "composer-lock-btn";
btn.textContent = locked ? "\u{1F512}" : "\u{1F513}";
btn.style.cssText =
"cursor:pointer;margin-left:10px;font-size:1.1em;user-select:none;opacity:" +
(locked ? "1" : "0.5");
btn.addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
locked = !locked;
btn.textContent = locked ? "\u{1F512}" : "\u{1F513}";
btn.style.opacity = locked ? "1" : "0.5";
updateButtons();
});
title.appendChild(btn);
updateButtons();
}
const observer = new MutationObserver(() => {
const rc = document.getElementById("reply-control");
if (rc && rc.classList.contains("open")) {
attachBlocker(rc);
injectPadlock();
updateButtons();
}
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["class"],
});
const rc = document.getElementById("reply-control");
if (rc && rc.classList.contains("open")) {
attachBlocker(rc);
injectPadlock();
updateButtons();
}
})();