From dd029ce05747400e8c759787907208ce91b57e85 Mon Sep 17 00:00:00 2001
From: awsr <43862868+awsr@users.noreply.github.com>
Date: Sun, 2 Nov 2025 02:15:24 -0800
Subject: [PATCH 1/3] Fix settings conflict that caused UI desync
Because these were being counted as regular settings, the Apply Settings button would revert any changes made in the Detailer section and make the settings become out of sync with the UI (until they were re-saved by changing a value in the Detailers section).
---
modules/shared.py | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/modules/shared.py b/modules/shared.py
index 35844e362..f12a6dea9 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -619,22 +619,6 @@ options_templates.update(options_section(('postprocessing', "Postprocessing"), {
"initial_noise_multiplier": OptionInfo(1.0, "Noise multiplier for image processing", gr.Slider, {"minimum": 0.1, "maximum": 1.5, "step": 0.01, "visible": False}),
"postprocessing_sep_detailer": OptionInfo("
Detailer
", "", gr.HTML),
- "detailer_model": OptionInfo("Detailer", "Detailer model", gr.Radio, lambda: {"choices": [x.name() for x in detailers], "visible": False}),
- "detailer_classes": OptionInfo("", "Detailer classes", gr.Textbox, { "visible": False}),
- "detailer_conf": OptionInfo(0.6, "Min confidence", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}),
- "detailer_max": OptionInfo(2, "Max detected", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1, "visible": False}),
- "detailer_iou": OptionInfo(0.5, "Max overlap", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}),
- "detailer_sigma_adjust": OptionInfo(1.0, "Detailer sigma adjust", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}),
- "detailer_sigma_adjust_max": OptionInfo(1.0, "Detailer sigma end", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}),
- "detailer_min_size": OptionInfo(0.0, "Min object size", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}),
- "detailer_max_size": OptionInfo(1.0, "Max object size", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}),
- "detailer_padding": OptionInfo(20, "Item padding", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": False}),
- "detailer_blur": OptionInfo(10, "Item edge blur", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": False}),
- "detailer_models": OptionInfo(['face-yolo8n'], "Detailer models", gr.Dropdown, lambda: {"multiselect":True, "choices": list(yolo.list), "visible": False}),
- "detailer_args": OptionInfo("", "Detailer args", gr.Textbox, { "visible": False}),
- "detailer_merge": OptionInfo(False, "Merge multiple results from each detailer model", gr.Checkbox, {"visible": False}),
- "detailer_sort": OptionInfo(False, "Sort detailer output by location", gr.Checkbox, {"visible": False}),
- "detailer_save": OptionInfo(False, "Include detection results", gr.Checkbox, {"visible": False}),
"detailer_unload": OptionInfo(False, "Move detailer model to CPU when complete"),
"detailer_augment": OptionInfo(True, "Detailer use model augment"),
@@ -789,6 +773,24 @@ options_templates.update(options_section(('hidden_options', "Hidden options"), {
'schedulers_max_shift': OptionInfo(1.15, "Sampler max shift", gr.Slider, {"minimum": 0.0, "maximum": 4.0, "step": 0.01, "visible": False}),
'uni_pc_variant': OptionInfo("bh2", "UniPC variant", gr.Radio, {"choices": ["bh1", "bh2", "vary_coeff"], "visible": False}),
'uni_pc_skip_type': OptionInfo("time_uniform", "UniPC skip type", gr.Radio, {"choices": ["time_uniform", "time_quadratic", "logSNR"], "visible": False}),
+
+ # detailer settings are handled separately
+ "detailer_model": OptionInfo("Detailer", "Detailer model", gr.Radio, lambda: {"choices": [x.name() for x in detailers], "visible": False}),
+ "detailer_classes": OptionInfo("", "Detailer classes", gr.Textbox, { "visible": False}),
+ "detailer_conf": OptionInfo(0.6, "Min confidence", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}),
+ "detailer_max": OptionInfo(2, "Max detected", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1, "visible": False}),
+ "detailer_iou": OptionInfo(0.5, "Max overlap", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}),
+ "detailer_sigma_adjust": OptionInfo(1.0, "Detailer sigma adjust", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}),
+ "detailer_sigma_adjust_max": OptionInfo(1.0, "Detailer sigma end", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}),
+ "detailer_min_size": OptionInfo(0.0, "Min object size", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}),
+ "detailer_max_size": OptionInfo(1.0, "Max object size", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}),
+ "detailer_padding": OptionInfo(20, "Item padding", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": False}),
+ "detailer_blur": OptionInfo(10, "Item edge blur", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": False}),
+ "detailer_models": OptionInfo(['face-yolo8n'], "Detailer models", gr.Dropdown, lambda: {"multiselect":True, "choices": list(yolo.list), "visible": False}),
+ "detailer_args": OptionInfo("", "Detailer args", gr.Textbox, { "visible": False}),
+ "detailer_merge": OptionInfo(False, "Merge multiple results from each detailer model", gr.Checkbox, {"visible": False}),
+ "detailer_sort": OptionInfo(False, "Sort detailer output by location", gr.Checkbox, {"visible": False}),
+ "detailer_save": OptionInfo(False, "Include detection results", gr.Checkbox, {"visible": False}),
}))
From 558d2f0f02e870f647910e6836d028f815ea495e Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Sun, 2 Nov 2025 06:18:32 -0500
Subject: [PATCH 2/3] fix samples check
Signed-off-by: Vladimir Mandic
---
modules/processing.py | 11 +++++------
wiki | 2 +-
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/modules/processing.py b/modules/processing.py
index 2f8c0c7aa..22b852fd0 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -307,16 +307,15 @@ def process_samples(p: StableDiffusionProcessing, samples):
info = create_infotext(p, p.prompts, p.seeds, p.subseeds, index=i)
images.save_image(Image.fromarray(sample), path=p.outpath_samples, basename="", seed=p.seeds[i], prompt=p.prompts[i], extension=shared.opts.samples_format, info=info, p=p, suffix="-before-detailer")
sample = detailer.detail(sample, p)
- if sample is not None:
- if isinstance(sample, list) and len(sample) > 1:
+ if isinstance(sample, list):
+ if len(sample) > 0:
image = Image.fromarray(sample[0])
+ if len(sample) > 1:
annotated = Image.fromarray(sample[1])
out_images.append(annotated)
out_infotexts.append("Detailer annotations")
- elif isinstance(sample, list):
- image = Image.fromarray(sample[0])
- else:
- image = Image.fromarray(sample)
+ elif sample is not None:
+ image = Image.fromarray(sample)
if p.color_corrections is not None and i < len(p.color_corrections):
p.ops.append('color')
diff --git a/wiki b/wiki
index 213bdc836..6fc069677 160000
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit 213bdc836534bc29ed353dc89b5b582e455a9bf5
+Subproject commit 6fc0696770923e78e1ae07cb849942568ec11dde
From 3f0a53f5e4c63a09a27b7181f1f6bbd6d5e78866 Mon Sep 17 00:00:00 2001
From: Vladimir Mandic
Date: Sun, 2 Nov 2025 06:29:17 -0500
Subject: [PATCH 3/3] cleanup
Signed-off-by: Vladimir Mandic
---
CHANGELOG.md | 19 ++++++++++---------
modules/timer.py | 2 +-
modules/ui_settings.py | 3 ++-
3 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ab3a0783e..5fe980cb9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
# Change Log for SD.Next
-## Update for 2025-11-01
+## Update for 2025-11-02
- **Features**
- **detailer**
@@ -10,17 +10,18 @@
- add inline wildcards using curly braces syntax
- add setting to control `cudnn` enable/disable
- **Fixes**
+ - fix: better handling of detailer settings, thanks @awsr
- fix: cleanup `--optional` installer
- fix: guard against multi-controlnet in hires
- fix: update diffusers
- - fix: inpaint
- - fix: model type detection
- - fix: version detection when cloned with `.git` suffix
- - fix: init `sdnq` on video model load
- - fix: add vae scale override for chrono
- - fix: add tracing to model detection
- - ui: fix full-screen image viewer buttons with non-standard ui theme
- - ui: control tab show override section
+ - fix: inpaint handling
+ - fix: model type detection
+ - fix: version detection when cloned with `.git` suffix, thanks @awsr
+ - fix: init `sdnq` on video model load
+ - fix: add vae scale override for chrono
+ - fix: add tracing to model detection
+ - ui: fix full-screen image viewer buttons with non-standard ui theme
+ - ui: control tab show override section
## Update for 2025-10-31
diff --git a/modules/timer.py b/modules/timer.py
index d94735902..082e293b6 100644
--- a/modules/timer.py
+++ b/modules/timer.py
@@ -4,7 +4,7 @@ import sys
try:
- default_min_time = float(os.environ.get('SD_MIN_TIMER', '0.05'))
+ default_min_time = float(os.environ.get('SD_MIN_TIMER', '0.1'))
except Exception:
default_min_time = 0.1
diff --git a/modules/ui_settings.py b/modules/ui_settings.py
index 880871530..5a3cc5cdf 100644
--- a/modules/ui_settings.py
+++ b/modules/ui_settings.py
@@ -208,7 +208,6 @@ def create_ui():
if (section_id, section_text) not in sections:
sections.append((section_id, section_text))
- shared.log.debug(f'Settings: sections={len(sections)} settings={len(shared.opts.list())}/{len(list(shared.opts.data_labels))} quicksettings={len(quicksettings_list)}')
with gr.Tabs(elem_id="settings"):
quicksettings_list.clear()
for (section_id, section_text) in sections:
@@ -241,6 +240,8 @@ def create_ui():
create_dirty_indicator("show_all_pages", [])
request_notifications = gr.Button(value='Request browser notifications', elem_id="request_notifications", visible=False)
+ shared.log.debug(f'Settings: sections={len(sections)} settings={len(shared.opts.list())}/{len(list(shared.opts.data_labels))} quicksettings={len(quicksettings_list)}')
+
with gr.TabItem("Update", id="system_update", elem_id="tab_update"):
from modules import update
update.create_ui()