diff --git a/CHANGELOG.md b/CHANGELOG.md index 299e92bd8..0f6afa646 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -101,6 +101,7 @@ - fix theme list refresh - fix extensions update information in ui - fix model merge manual merge settings, thanks @AI-Casanova + - fix gradio instant update issues for textboxes in quicksettings - bind controlnet extension to last known working commit, thanks @Aptronymist - prompts-from-file fix resizable prompt area diff --git a/javascript/settings.js b/javascript/settings.js index 0fa388ec3..b20083da9 100644 --- a/javascript/settings.js +++ b/javascript/settings.js @@ -8,9 +8,9 @@ const monitoredOpts = [ ]; const AppyOpts = [ - { compact_view: (val) => toggleCompact(val) }, + { compact_view: (val, old) => toggleCompact(val, old) }, { gradio_theme: (val, old) => setTheme(val, old) }, - { font_size: (val) => setFontSize(val) }, + { font_size: (val, old) => setFontSize(val, old) }, ]; async function updateOpts(json_string) { diff --git a/javascript/ui.js b/javascript/ui.js index 424803e0b..8edfba11b 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -66,7 +66,7 @@ function extract_image_from_gallery(gallery) { } async function setTheme(val, old) { - if (!old) return; + if (!old || val === old) return; const links = Array.from(document.getElementsByTagName('link')).filter((l) => l.href.includes(old)); for (const link of links) { const href = link.href.replace(old, val); @@ -80,8 +80,9 @@ async function setTheme(val, old) { } } -function setFontSize(val) { +function setFontSize(val, old) { const size = val || opts.font_size; + if (size === old) return; document.documentElement.style.setProperty('--font-size', `${size}px`); gradioApp().style.setProperty('--font-size', `${size}px`); gradioApp().style.setProperty('--text-xxs', `${size - 3}px`); @@ -443,8 +444,9 @@ function createThemeElement() { return el; } -function toggleCompact(val) { - // log('toggleCompact', val); +function toggleCompact(val, old) { + if (val === old) return; + log('toggleCompact', val, old); if (val) { gradioApp().style.setProperty('--layout-gap', 'var(--spacing-md)'); gradioApp().querySelectorAll('input[type=range]').forEach((el) => el.classList.add('hidden')); diff --git a/modules/shared.py b/modules/shared.py index fb5e6aa4e..57c982fcf 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -3,6 +3,7 @@ import os import sys import time import json +import threading import contextlib from types import SimpleNamespace from urllib.parse import urlparse @@ -793,7 +794,7 @@ class Options: data_label = self.data_labels.get(key) return data_label.default if data_label is not None else None - def save(self, filename=None, silent=False): + def save_atomic(self, filename=None, silent=False): if filename is None: filename = self.filename if cmd_opts.freeze: @@ -828,6 +829,9 @@ class Options: except Exception as e: log.error(f'Saving settings failed: {filename} {e}') + def save(self, filename=None, silent=False): + threading.Thread(target=self.save_atomic, args=(filename, silent)).start() + def same_type(self, x, y): if x is None or y is None: return True diff --git a/modules/ui.py b/modules/ui.py index 77f1cb41b..b773f6231 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -105,7 +105,9 @@ def get_value_for_setting(key): value = getattr(opts, key) info = opts.data_labels[key] args = info.component_args() if callable(info.component_args) else info.component_args or {} - args = {k: v for k, v in args.items() if k not in {'precision', 'multiselect'}} + args = {k: v for k, v in args.items() if k not in {'precision', 'multiselect', 'visible'}} + # if not args: + # return gr.update() return gr.update(value=value, **args) @@ -258,7 +260,7 @@ def create_ui(startup_timer = None): return opts.dumpjson(), f'{len(changed)} Settings changed without save: {", ".join(changed)}' return opts.dumpjson(), f'{len(changed)} Settings changed{": " if len(changed) > 0 else ""}{", ".join(changed)}' - def run_settings_single(value, key): + def run_settings_single(value, key, progress=False): if not opts.same_type(value, opts.data_labels[key].default): return gr.update(visible=True), opts.dumpjson() if not opts.set(key, value): @@ -268,7 +270,7 @@ def create_ui(startup_timer = None): if cmd_opts.use_directml: directml_override_opts() opts.save(shared.config_filename) - log.debug(f'Setting changed: key={key}, value={value}') + log.debug(f'Setting changed: {key}={value} progress={progress}') return get_value_for_setting(key), opts.dumpjson() with gr.Blocks(analytics_enabled=False) as settings_interface: @@ -432,13 +434,17 @@ def create_ui(startup_timer = None): for _i, k, _item in quicksettings_list: component = component_dict[k] info = opts.data_labels[k] - change_handler = component.release if hasattr(component, 'release') else component.change - change_handler( - fn=lambda value, k=k: run_settings_single(value, key=k), - inputs=[component], - outputs=[component, text_settings], - show_progress=info.refresh is not None, - ) + if isinstance(component, gr.components.Textbox): + change_handlers = [component.blur, component.submit] + else: + change_handlers = [component.release if hasattr(component, 'release') else component.change] + for change_handler in change_handlers: + change_handler( + fn=lambda value, k=k, progress=info.refresh is not None: run_settings_single(value, key=k, progress=progress), + inputs=[component], + outputs=[component, text_settings], + show_progress=info.refresh is not None, + ) dummy_component = gr.Textbox(visible=False, value='dummy') button_set_checkpoint = gr.Button('Change model', elem_id='change_checkpoint', visible=False) diff --git a/modules/xadapter/unet_adapter.py b/modules/xadapter/unet_adapter.py index b99639466..fa11c7cf8 100644 --- a/modules/xadapter/unet_adapter.py +++ b/modules/xadapter/unet_adapter.py @@ -1014,7 +1014,7 @@ class UNet2DConditionModel(ModelMixin, ConfigMixin, UNet2DConditionLoadersMixin) if is_bridge: if up_block_additional_residual[0].shape != sample.shape: - print('HERE SKIP1') + pass # TODO VM patch elif fusion_guidance_scale is not None: sample = sample + fusion_guidance_scale * (up_block_additional_residual.pop(0) - sample) else: @@ -1053,7 +1053,7 @@ class UNet2DConditionModel(ModelMixin, ConfigMixin, UNet2DConditionLoadersMixin) ################# bridge usage ################# if is_bridge and len(up_block_additional_residual) > 0: if sample.shape != up_block_additional_residual[0].shape: - print('HERE SKIP2') + pass # TODO VM PATCH elif fusion_guidance_scale is not None: sample = sample + fusion_guidance_scale * (up_block_additional_residual.pop(0) - sample) else: