diff --git a/README.md b/README.md
index 316c2e9..253d5e3 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,11 @@ Desktop downloader for Windows with package-based queue management, multi-provid
## Changelog
+### 2.0.12
+
+- Prevent static headings, labels, hints, and card text from being selected throughout Settings.
+- Keep editable fields and text areas selectable for normal copy and paste.
+
### 2.0.11
- Keep Account Overview and Usage Rules inside the same fixed layout frame.
diff --git a/package-lock.json b/package-lock.json
index b13a0ac..68b3598 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "real-debrid-downloader",
- "version": "2.0.11",
+ "version": "2.0.12",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "real-debrid-downloader",
- "version": "2.0.11",
+ "version": "2.0.12",
"license": "MIT",
"dependencies": {
"adm-zip": "0.6.0",
diff --git a/package.json b/package.json
index 0855749..3341c5c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "real-debrid-downloader",
- "version": "2.0.11",
+ "version": "2.0.12",
"description": "Desktop downloader",
"main": "build/main/main/main.js",
"author": "Sucukdeluxe",
diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx
index 3b82d77..db7b750 100644
--- a/src/renderer/App.tsx
+++ b/src/renderer/App.tsx
@@ -4796,7 +4796,7 @@ export function App(): ReactElement {
return (
{
event.preventDefault();
if (draggedPackageIdRef.current) { return; }
diff --git a/src/renderer/styles.css b/src/renderer/styles.css
index 974123e..7f73430 100644
--- a/src/renderer/styles.css
+++ b/src/renderer/styles.css
@@ -1067,13 +1067,23 @@ body,
margin-left: 26px;
}
-.settings-shell {
- display: grid;
- grid-template-rows: auto 1fr;
- gap: 8px;
- height: 100%;
- min-height: 0;
-}
+.settings-shell {
+ display: grid;
+ grid-template-rows: auto 1fr;
+ gap: 8px;
+ height: 100%;
+ min-height: 0;
+}
+
+.app-shell.settings-active {
+ user-select: none;
+}
+
+.app-shell.settings-active input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
+.app-shell.settings-active textarea,
+.app-shell.settings-active [contenteditable]:not([contenteditable="false"]) {
+ user-select: text;
+}
.settings-toolbar {
display: flex;
diff --git a/tests/settings-selection.test.ts b/tests/settings-selection.test.ts
new file mode 100644
index 0000000..785f8de
--- /dev/null
+++ b/tests/settings-selection.test.ts
@@ -0,0 +1,13 @@
+import { readFileSync } from "node:fs";
+import { describe, expect, it } from "vitest";
+
+const styles = readFileSync(new URL("../src/renderer/styles.css", import.meta.url), "utf8");
+const appSource = readFileSync(new URL("../src/renderer/App.tsx", import.meta.url), "utf8");
+
+describe("settings text selection", () => {
+ it("blocks selection across the active settings view and its dialogs while preserving editable fields", () => {
+ expect(appSource).toContain('${tab === "settings" ? " settings-active" : ""}');
+ expect(styles).toMatch(/\.app-shell\.settings-active\s*{[^}]*user-select:\s*none;/s);
+ expect(styles).toMatch(/\.app-shell\.settings-active input:not\(\[type="checkbox"\]\):not\(\[type="radio"\]\):not\(\[type="range"\]\),\s*\.app-shell\.settings-active textarea,\s*\.app-shell\.settings-active \[contenteditable\]:not\(\[contenteditable="false"\]\)\s*{[^}]*user-select:\s*text;/s);
+ });
+});