meltygui 0.1.0__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {meltygui-0.1.0 → meltygui-0.1.3}/.gitignore +1 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/PKG-INFO +11 -6
- {meltygui-0.1.0 → meltygui-0.1.3}/README.md +4 -2
- meltygui-0.1.3/docs/APPS.md +340 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/docs/DEVELOPMENT.md +39 -5
- meltygui-0.1.3/docs/INPUT_RECORDING.md +81 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/docs/PUBLISHING.md +24 -3
- meltygui-0.1.3/examples/render_overlay.py +36 -0
- meltygui-0.1.3/examples/tile_sibling_links.py +50 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/__init__.py +15 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/accounts/internet_accounts.py +27 -17
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/__init__.py +26 -10
- meltygui-0.1.3/meltygui/chat/__main__.py +5 -0
- meltygui-0.1.3/meltygui/chat/assets/source-icons/LICENSE +21 -0
- meltygui-0.1.3/meltygui/chat/assets/source-icons/README.md +4 -0
- meltygui-0.1.3/meltygui/chat/assets/source-icons/claude.png +0 -0
- meltygui-0.1.3/meltygui/chat/assets/source-icons/claude.svg +1 -0
- meltygui-0.1.3/meltygui/chat/assets/source-icons/codex.png +0 -0
- meltygui-0.1.3/meltygui/chat/assets/source-icons/codex.svg +1 -0
- meltygui-0.1.3/meltygui/chat/auto_titles.py +79 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/backends.py +1 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/chat_interface.py +49 -22
- meltygui-0.1.3/meltygui/chat/chat_service.py +517 -0
- meltygui-0.1.3/meltygui/chat/claude_code.py +1054 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/codex_proxy.py +11 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/codex_settings.py +26 -0
- meltygui-0.1.3/meltygui/chat/main.py +202 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/metadata.py +4 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/chain_converters.py +2 -2
- meltygui-0.1.3/meltygui/code/codec_registry.py +40 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/core_syntax.py +15 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/file_converters.py +40 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/live_view.py +9 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/melty_scan.py +257 -5
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/new_codecs.py +69 -32
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/new_converters.py +19 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/README.md +8 -5
- meltygui-0.1.3/meltygui/core/automation/input_recording_core.py +60 -0
- meltygui-0.1.3/meltygui/core/automation/input_replay.py +180 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/mcp_server.py +5 -4
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/orchestration_core.py +6 -4
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/cache/invalidation_decoration.py +24 -0
- meltygui-0.1.3/meltygui/core/cache/invalidation_tracker.py +82 -0
- meltygui-0.1.3/meltygui/core/cache/mask_batch.py +188 -0
- meltygui-0.1.3/meltygui/core/cache/parameter_dependencies.py +52 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/cache/tile_cache.py +609 -482
- meltygui-0.1.3/meltygui/core/cache/tile_marks.py +96 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/dict_conversion.py +3 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/load_save_v2.py +47 -21
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/core_render.py +165 -339
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/definition_hotswap.py +54 -0
- meltygui-0.1.3/meltygui/core/diagnostics/edge_motion_guard.py +621 -0
- meltygui-0.1.3/meltygui/core/diagnostics/fps_counter.py +25 -0
- meltygui-0.1.3/meltygui/core/diagnostics/geometry_jitter.py +208 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/gpu_frame_timer.py +9 -3
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/resize_trace.py +4 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/files/file_explorer_core.py +45 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/files/file_tree_core.py +1 -1
- meltygui-0.1.3/meltygui/core/files/path_icons.py +76 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/cuda_context_core.py +6 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/cuda_interop_core.py +32 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/overlay_renderer.py +37 -9
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/screenshot.py +3 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/drag_drop_core.py +16 -6
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/input_handler.py +71 -23
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/pynput_backend.py +6 -3
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/layout/column_core.py +137 -34
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/layout/dropdown_core.py +3 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/layout/edge_constraints.py +6 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/layout/header_runtime.py +1 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/layout/layout_core.py +1 -1
- meltygui-0.1.3/meltygui/core/layout/tile_links.py +180 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/layout/tile_manager_core.py +221 -44
- meltygui-0.1.3/meltygui/core/layout/tile_resize.py +54 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/melty.py +358 -94
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/module_map.json +22 -3
- meltygui-0.1.3/meltygui/core/rendering/fast_view.py +538 -0
- meltygui-0.1.3/meltygui/core/rendering/injected_state.py +62 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/mode.py +305 -259
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/modes.py +0 -5
- meltygui-0.1.3/meltygui/core/rendering/overlay.py +353 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/parameter_core.py +4 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/render_dispatch.py +13 -46
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/render_funcs.py +0 -1
- meltygui-0.1.3/meltygui/core/rendering/view_identity.py +199 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/app.py +282 -37
- meltygui-0.1.3/meltygui/core/runtime/app_settings.py +183 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/background.py +10 -1
- meltygui-0.1.3/meltygui/core/runtime/launch_override.py +223 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/toggles.py +69 -7
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/services/terminal_core.py +4 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/styling/fonts.py +32 -15
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/styling/warm_start.py +32 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/dock_core.py +3 -3
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/geometry_feed.py +97 -5
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/glfw_utils.py +126 -27
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/os_frame.py +79 -23
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/surface.py +80 -11
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/titlebar.py +171 -42
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/window_visibility.py +30 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/file_header.py +1 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/live_view_views.py +1 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/pending_save.py +34 -3
- meltygui-0.1.3/meltygui/editor/source_preview.py +32 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/text_editor.py +11 -4
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/usage_picker.py +2 -2
- meltygui-0.1.3/meltygui/examples/settings_demo.py +28 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/tile_manager_demo.py +19 -4
- meltygui-0.1.3/meltygui/examples/voxel_transfer_paths.py +213 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/files/fast_file_explorer.py +4 -6
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/__init__.py +1 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/shader_compiler.py +9 -3
- meltygui-0.1.3/meltygui/model/breakpoint_model.py +67 -0
- meltygui-0.1.3/meltygui/model/chat_folder_model.py +163 -0
- meltygui-0.1.3/meltygui/model/chat_model.py +178 -0
- meltygui-0.1.3/meltygui/model/code_dict_model.py +870 -0
- meltygui-0.1.3/meltygui/model/cuda_buffer_model.py +127 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/cuda_tensor_model.py +1 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/cuda_texture_model.py +80 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/dropdown_model.py +16 -1
- meltygui-0.1.3/meltygui/model/file_location_model.py +118 -0
- meltygui-0.1.3/meltygui/model/folder_icon_model.py +348 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/format_model.py +4 -3
- meltygui-0.1.3/meltygui/model/input_recording_model.py +418 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/lut_model.py +113 -3
- meltygui-0.1.3/meltygui/model/source_snapshot_model.py +288 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/tensor_model.py +12 -1
- meltygui-0.1.3/meltygui/model/texture_model.py +250 -0
- meltygui-0.1.3/meltygui/model/tile_model.py +48 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/trace_model.py +29 -10
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/trace_report_model.py +38 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/models/file_meta.py +96 -9
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/chat_state.py +21 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/core_undo.py +0 -4
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/file_state.py +6 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/new_core_model.py +109 -63
- meltygui-0.1.3/meltygui/state/path_icon_state.py +23 -0
- meltygui-0.1.3/meltygui/state/texture_state.py +21 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/trace_state.py +4 -1
- meltygui-0.1.3/meltygui/state/view_reference.py +20 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/account_view.py +1 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/action_view.py +1 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/chat_decoration_view.py +1 -1
- meltygui-0.1.3/meltygui/view/chat_sidebar_view.py +440 -0
- meltygui-0.1.3/meltygui/view/chat_source_icon_view.py +48 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/chat_view.py +183 -291
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/code_view.py +62 -69
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/collection_view.py +524 -197
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/color_view.py +218 -3
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/control_view.py +64 -16
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/decoration_view.py +5 -4
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/dropdown_view.py +305 -24
- meltygui-0.1.3/meltygui/view/file_icon_view.py +60 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/file_view.py +344 -112
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/graph_view.py +3 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/header_view.py +78 -64
- meltygui-0.1.3/meltygui/view/input_recording_view.py +50 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/inspection_view.py +81 -12
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/layout_view.py +3 -3
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/menu_view.py +18 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/orchestration_view.py +1 -1
- meltygui-0.1.3/meltygui/view/path_icon_view.py +105 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/text_view.py +89 -21
- meltygui-0.1.3/meltygui/view/texture_view.py +244 -0
- meltygui-0.1.3/meltygui/view/tile_view.py +316 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/trace_view.py +59 -11
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/voxel_cuda_view.py +15 -7
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/voxel_view.py +18 -14
- {meltygui-0.1.0 → meltygui-0.1.3}/pyproject.toml +8 -6
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/conftest.py +2 -2
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/profile_render_wrapper.py +4 -2
- meltygui-0.1.3/tests/test_app_exit_flush.py +103 -0
- meltygui-0.1.3/tests/test_app_settings.py +161 -0
- meltygui-0.1.3/tests/test_background_palette.py +83 -0
- meltygui-0.1.3/tests/test_breakpoint_model.py +139 -0
- meltygui-0.1.3/tests/test_cached_input_delivery.py +103 -0
- meltygui-0.1.3/tests/test_capture_passes.py +107 -0
- meltygui-0.1.3/tests/test_chat_auto_titles.py +97 -0
- meltygui-0.1.3/tests/test_chat_claude_code.py +625 -0
- meltygui-0.1.3/tests/test_chat_codex_fast.py +139 -0
- meltygui-0.1.3/tests/test_chat_main.py +69 -0
- meltygui-0.1.3/tests/test_chat_presentation.py +241 -0
- meltygui-0.1.3/tests/test_chat_service.py +398 -0
- meltygui-0.1.3/tests/test_chat_token_usage.py +61 -0
- meltygui-0.1.3/tests/test_chat_turn_status.py +76 -0
- meltygui-0.1.3/tests/test_child_surface_cache_keepalive.py +84 -0
- meltygui-0.1.3/tests/test_clean_surface_skip.py +140 -0
- meltygui-0.1.3/tests/test_click_disambiguation.py +124 -0
- meltygui-0.1.3/tests/test_code_dict.py +262 -0
- meltygui-0.1.3/tests/test_code_dict_scenarios.py +1137 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_column_edge_solve.py +31 -2
- meltygui-0.1.3/tests/test_column_right_drag_display_wall.py +151 -0
- meltygui-0.1.3/tests/test_context_menu_placement.py +21 -0
- meltygui-0.1.3/tests/test_control_paint.py +34 -0
- meltygui-0.1.3/tests/test_crash_report_store.py +63 -0
- meltygui-0.1.3/tests/test_cuda_image_interop.py +80 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_cuda_interop.py +6 -3
- meltygui-0.1.3/tests/test_deferred_view_returns.py +37 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_definition_relocation.py +73 -3
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_draw_state_parent_geometry.py +67 -1
- meltygui-0.1.3/tests/test_dropdown_divider.py +16 -0
- meltygui-0.1.3/tests/test_edge_motion_guard.py +512 -0
- meltygui-0.1.3/tests/test_fast_draw_collection.py +141 -0
- meltygui-0.1.3/tests/test_fast_draw_dropdown.py +107 -0
- meltygui-0.1.3/tests/test_fast_menu_bar.py +32 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_file_metadata_model.py +125 -0
- meltygui-0.1.3/tests/test_file_rows_overlay.py +108 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_file_type_codecs.py +57 -11
- meltygui-0.1.3/tests/test_file_watch_start.py +36 -0
- meltygui-0.1.3/tests/test_folder_icons.py +228 -0
- meltygui-0.1.3/tests/test_font_backing_scale.py +69 -0
- meltygui-0.1.3/tests/test_fps_counter.py +46 -0
- meltygui-0.1.3/tests/test_freeze_scrollbar_overlay.py +236 -0
- meltygui-0.1.3/tests/test_geometry_feed_grace.py +78 -0
- meltygui-0.1.3/tests/test_geometry_jitter.py +229 -0
- meltygui-0.1.3/tests/test_glfw_window_app_name.py +74 -0
- meltygui-0.1.3/tests/test_gpu_frame_timer.py +59 -0
- meltygui-0.1.3/tests/test_held_input.py +27 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_hotswap_preserves_runtime_state.py +41 -0
- meltygui-0.1.3/tests/test_image_texture.py +121 -0
- meltygui-0.1.3/tests/test_initial_child_placement.py +50 -0
- meltygui-0.1.3/tests/test_input_recording.py +242 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_lut_model.py +88 -0
- meltygui-0.1.3/tests/test_mask_batch.py +106 -0
- meltygui-0.1.3/tests/test_native_collision_fallback.py +125 -0
- meltygui-0.1.3/tests/test_native_collision_surface.py +118 -0
- meltygui-0.1.3/tests/test_native_live_resize.py +143 -0
- meltygui-0.1.3/tests/test_native_resize_workarea.py +131 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_native_windows.py +2 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_os_frame.py +56 -2
- meltygui-0.1.3/tests/test_overlay_submission_state.py +100 -0
- meltygui-0.1.3/tests/test_path_icon_view.py +75 -0
- meltygui-0.1.3/tests/test_recent_files.py +91 -0
- meltygui-0.1.3/tests/test_release_workflow.py +105 -0
- meltygui-0.1.3/tests/test_render_background.py +183 -0
- meltygui-0.1.3/tests/test_render_overlay.py +448 -0
- meltygui-0.1.3/tests/test_restored_resource_ownership.py +73 -0
- meltygui-0.1.3/tests/test_retina_tile_capture.py +78 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_row_edge_solve.py +1 -0
- meltygui-0.1.3/tests/test_shadow_capture_gl.py +177 -0
- meltygui-0.1.3/tests/test_source_site_keys.py +210 -0
- meltygui-0.1.3/tests/test_startup_imports.py +118 -0
- meltygui-0.1.3/tests/test_texture_overlay.py +150 -0
- meltygui-0.1.3/tests/test_tile_frame_reuse.py +65 -0
- meltygui-0.1.3/tests/test_tile_hotswap_content.py +93 -0
- meltygui-0.1.3/tests/test_tile_links.py +706 -0
- meltygui-0.1.3/tests/test_tile_manager.py +476 -0
- meltygui-0.1.3/tests/test_tile_resize_replay.py +179 -0
- meltygui-0.1.3/tests/test_toggles_color.py +20 -0
- meltygui-0.1.3/tests/test_unmanaged_window_frames.py +44 -0
- meltygui-0.1.3/tests/test_view_icon_locate.py +68 -0
- meltygui-0.1.3/tests/test_view_identity.py +91 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_voxel_backends.py +3 -1
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_voxel_ownership.py +5 -2
- meltygui-0.1.3/tests/test_window_call_state.py +50 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_window_collision_investigation.py +27 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_window_comment_overrides.py +4 -1
- meltygui-0.1.0/docs/APPS.md +0 -103
- meltygui-0.1.0/meltygui/core/cache/invalidation_tracker.py +0 -43
- meltygui-0.1.0/meltygui/core/diagnostics/fps_counter.py +0 -39
- meltygui-0.1.0/meltygui/editor/source_preview.py +0 -16
- meltygui-0.1.0/meltygui/graphics/texture_manager.py +0 -170
- meltygui-0.1.0/meltygui/model/chat_model.py +0 -86
- meltygui-0.1.0/meltygui/model/texture_model.py +0 -146
- meltygui-0.1.0/meltygui/model/tile_model.py +0 -24
- meltygui-0.1.0/meltygui/view/texture_view.py +0 -480
- meltygui-0.1.0/meltygui/view/tile_view.py +0 -38
- meltygui-0.1.0/tests/test_chat_presentation.py +0 -74
- meltygui-0.1.0/tests/test_fps_counter.py +0 -28
- meltygui-0.1.0/tests/test_tile_manager.py +0 -192
- {meltygui-0.1.0 → meltygui-0.1.3}/LICENSE +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/docs/SUPPORT_WHEELS.md +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/examples/tensor_live.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/examples/tile_manager.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/examples/voxel_playground.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/accounts/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/activity.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/chat_proxy.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/codex_transport.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/command_parser.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/images.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/messages.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/chat/writer_locks.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/basic_converters.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/code_checks.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/fileref.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/hotswap_guard.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/libcst_conversion.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/live_instrument.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/project_code.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/source_context.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/symbol_roster.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/syntax_check.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/code/syntax_check_worker.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/fim.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/fim_context.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/providers/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/providers/anthropic_oauth.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/providers/anthropic_requests.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/providers/claude.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/providers/claude_usage.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/providers/codex_accounts.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/providers/copilot.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/providers/oauth_popup.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/providers/ollama.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/completion/providers/profiles.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/action_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/collection_action.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/mcp_eval.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/mcp_hotswap.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/mcp_query.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/query_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/search_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/selector_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/automation/value_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/cache/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/cache/cache_diagnostics.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/bubbling.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/cache_tree.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/chain.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/converter_register.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/data_decoration.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/dict_conversion_util.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/dynamic_obj.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/graph_compare.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/missing_saved_class.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/path_finder.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/conversion/render_host.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/attribute_churn.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/inspection_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/monitor_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/notifications.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/perf_trace.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/profile_decoration.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/screenshot_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/session_status.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/diagnostics/trace_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/files/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/files/file_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/files/file_watch_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/files/import_graph_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/files/metadata_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/cuda_kernel_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/framebuffer_recorder.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/gl_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/lut_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/scene_target.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/shader_func.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/tensor_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/text_texture.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/graphics/wayland_color.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/collision.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/hypr_left_drag.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/input_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/mouse_cursor.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/space_mouse.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/touchpad_backend.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/input/view_selection.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/layout/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/layout/cursor_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/layout/grid_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/layout/header_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/module_names.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/core_decoration.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/core_render_helpers.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/func_metadata.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/mode_defaults.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/shaped.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/rendering/window_decoration.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/app_session.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/extensions.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/gc_manager.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/lifecycle.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/paths.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/settings.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/singleton.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/thread_safe_bool.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/runtime/thread_signal.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/services/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/services/account_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/services/chat_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/services/claude_terminal_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/services/terminal_runtime.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/styling/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/styling/color_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/styling/global_style.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/styling/style.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/styling/style_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/backends/PYIMGUI_LICENSE +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/backends/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/backends/imgui_renderer.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/backends/native_wayland.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/backends/protocols/xdg-decoration-unstable-v1.xml +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/backends/protocols/xdg-shell.xml +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/backends/wayland_protocol.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/frame_geometry.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/titlebar_buttons.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/wayland_move.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/window_api.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/core/windowing/window_constants.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/debug/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/debug/app_view_utils.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/bash_syntax.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/code_line_fast.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/diff.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/external_changes.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/live_usage.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/roster_tints.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/source_tools.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/source_ui.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/editor/spell_check.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/events/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/events/example.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/columns_demo.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/columns_window_demo.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/context_menu_demo.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/context_menu_window_demo.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/gui_playground.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/live_view_playground.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/lora.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/lora_data.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/lora_policies.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/mode_demo.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/modifies_demo.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/scalar_policies.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/style_layouts.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/tint_demo.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/tint_functions.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/trace_demo.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/examples/two_windows.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/files/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/gnome_extension/lsd-window-geometry@latent-descent/extension.js +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/gnome_extension/lsd-window-geometry@latent-descent/lsd-window-geometry@latent-descent.iml +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/gnome_extension/lsd-window-geometry@latent-descent/metadata.json +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/base.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/examples.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/executor.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/filter.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/filter.pyi +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/generate_stubs.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/registry.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/shaders.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/stub_generator.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/graphics/texture_min_max.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/hdr_color.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/image_load.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/account_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/camera_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/code_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/code_proxy_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/collection_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/color_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/file_metadata_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/file_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/graph_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/icon_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/import_graph_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/layout_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/search_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/model/terminal_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/models/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/models/function_console.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/models/orchestration.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/pbr.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/png_unfilter.c +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/JetBrainsMono-Regular.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/THIRD_PARTY_NOTICES.md +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/dejavu/DejaVuSans-Bold.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/dejavu/DejaVuSans-ExtraLight.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/dejavu/DejaVuSans.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/dejavu/LICENSE.txt +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/fontawesome-LICENSE.txt +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/fontawesome-webfont.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/hdri/studio_small_09_1k.hdr +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/jetbrains-weights/JetBrainsMono-Bold.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/jetbrains-weights/JetBrainsMono-ExtraBold.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/jetbrains-weights/JetBrainsMono-ExtraLight.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/jetbrains-weights/JetBrainsMono-Light.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/jetbrains-weights/JetBrainsMono-Medium.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/jetbrains-weights/JetBrainsMono-SemiBold.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/jetbrains-weights/JetBrainsMono-Thin.ttf +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/jetbrains-weights/OFL.txt +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/resources/jetbrains-weights/README.md +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/account_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/animation_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/annotation_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/code_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/core_enums.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/core_markers.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/graph_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/inspection_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/menu_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/model_enums.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/orchestration_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/query_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/tensor_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/terminal_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/state/voxel_state.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/text_index.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/utils/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/utils/jump_to_code.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/utils/pkl_inspect.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/utils/render_utils.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/__init__.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/diagnostic_view.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/graph_cuda_view.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/input_view.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/lut_view.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/query_view.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/search_view.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/tab_view.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/tensor_view.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/terminal_view.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/meltygui/view/window_view.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/fixtures/terminal_before_runtime.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_chat_messages.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_column_frame_fit.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_column_maxes.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_core_relocation.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_core_syntax.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_cuda_context_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_cuda_direct_lines.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_cuda_interop_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_cuda_kernel_core.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_cuda_march.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_edge_graph_solve.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_file_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_file_watch_limits.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_frame_geometry_hotswap.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_fstring_highlight.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_function_console.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_glfw_window_editable_root.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_hdr_color.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_import_boundary.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_live_class_apply.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_live_function_apply.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_live_store_owner.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_native_background_drag.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_native_body_cursor.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_native_frame_contacts.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_nested_layout_right_drag.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_package_contract.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_pending_signature_lint.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_public_boundary.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_readme_examples.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_recompile_import_backfill.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_render_change_notification.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_render_context_injection.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_render_func_integration.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_render_host_surface_drag.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_saved_renderer_recovery.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_search_symbol_tables.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_shader_func.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_shaped.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_surface_body_resize.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_syntax_check_worker.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_tensor_controls.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_tensor_model.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_tensor_slices.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_terminal_live_migration.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_terminal_ownership.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_text_texture_contexts.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_typing_incremental_layout.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_voxel_roll_gl.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/test_windows_portability.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tests/untitled.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/native_wheels/build.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/native_wheels/build_in_container.sh +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/native_wheels/licenses/NVIDIA-CUDA-12.1-EULA.txt +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/native_wheels/licenses/boost.txt +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/native_wheels/licenses/imgui-MIT.txt +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/native_wheels/licenses/imstb_rectpack.h.license.txt +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/native_wheels/licenses/imstb_textedit.h.license.txt +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/native_wheels/licenses/imstb_truetype.h.license.txt +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/native_wheels/prepare.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/native_wheels/rewrite_imports.py +0 -0
- {meltygui-0.1.0 → meltygui-0.1.3}/tools/release.py +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: meltygui
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Immediate-mode Python UI, live inspection, HDR and tensor visualization
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
8
9
|
Classifier: Operating System :: Microsoft :: Windows
|
|
9
10
|
Classifier: Operating System :: POSIX :: Linux
|
|
10
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -17,8 +18,8 @@ Requires-Dist: glfw>=2.10
|
|
|
17
18
|
Requires-Dist: httpx>=0.27
|
|
18
19
|
Requires-Dist: jedi>=0.19
|
|
19
20
|
Requires-Dist: libcst>=1.4
|
|
20
|
-
Requires-Dist: mcp>=
|
|
21
|
-
Requires-Dist: meltygui-imgui[glfw]<2.0.
|
|
21
|
+
Requires-Dist: mcp>=2.0
|
|
22
|
+
Requires-Dist: meltygui-imgui[glfw]<2.0.2,>=2.0.1
|
|
22
23
|
Requires-Dist: numpy>=1.26
|
|
23
24
|
Requires-Dist: packaging>=24
|
|
24
25
|
Requires-Dist: pillow>=10
|
|
@@ -33,13 +34,15 @@ Requires-Dist: symspellpy>=6.7
|
|
|
33
34
|
Requires-Dist: tomlkit>=0.13
|
|
34
35
|
Requires-Dist: uvicorn>=0.30
|
|
35
36
|
Requires-Dist: watchdog>=4
|
|
37
|
+
Provides-Extra: claude
|
|
38
|
+
Requires-Dist: claude-agent-sdk>=0.2.152; extra == 'claude'
|
|
36
39
|
Provides-Extra: input
|
|
37
40
|
Requires-Dist: evdev>=1.7; (sys_platform == 'linux') and extra == 'input'
|
|
38
41
|
Requires-Dist: pynput>=1.7; extra == 'input'
|
|
39
42
|
Provides-Extra: profile
|
|
40
43
|
Requires-Dist: line-profiler>=4; extra == 'profile'
|
|
41
44
|
Provides-Extra: tensor
|
|
42
|
-
Requires-Dist: meltygui-pycuda<2026.
|
|
45
|
+
Requires-Dist: meltygui-pycuda<2026.3,>=2026.2; (sys_platform == 'linux') and extra == 'tensor'
|
|
43
46
|
Requires-Dist: torch>=2.2; extra == 'tensor'
|
|
44
47
|
Description-Content-Type: text/markdown
|
|
45
48
|
|
|
@@ -58,11 +61,13 @@ MeltyGUI is capable of rendering tensors exceeding 64GB in size. The primary cha
|
|
|
58
61
|
MeltyGUI is not yet published to PyPI. For now, install from a checkout using
|
|
59
62
|
[the setup guide](docs/DEVELOPMENT.md#setup).
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
Linux x86-64 uses Python 3.11, 3.12 or 3.13 and OpenGL 4.3. The UI and editor
|
|
65
|
+
also run on Apple Silicon macOS with Python 3.12, OpenGL 4.1 and Retina
|
|
66
|
+
rendering. CUDA tensor rendering requires PyTorch, an
|
|
63
67
|
NVIDIA GPU, a CUDA toolkit, and MeltyGUI's GL-enabled CUDA binding. The native
|
|
64
68
|
bindings install as prebuilt wheels on those targets; elsewhere installers
|
|
65
69
|
compile them, see [when no wheel matches](docs/SUPPORT_WHEELS.md#when-no-wheel-matches).
|
|
70
|
+
CUDA rendering is unavailable on macOS.
|
|
66
71
|
|
|
67
72
|
## Visualize a tensor
|
|
68
73
|
|
|
@@ -13,11 +13,13 @@ MeltyGUI is capable of rendering tensors exceeding 64GB in size. The primary cha
|
|
|
13
13
|
MeltyGUI is not yet published to PyPI. For now, install from a checkout using
|
|
14
14
|
[the setup guide](docs/DEVELOPMENT.md#setup).
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
Linux x86-64 uses Python 3.11, 3.12 or 3.13 and OpenGL 4.3. The UI and editor
|
|
17
|
+
also run on Apple Silicon macOS with Python 3.12, OpenGL 4.1 and Retina
|
|
18
|
+
rendering. CUDA tensor rendering requires PyTorch, an
|
|
18
19
|
NVIDIA GPU, a CUDA toolkit, and MeltyGUI's GL-enabled CUDA binding. The native
|
|
19
20
|
bindings install as prebuilt wheels on those targets; elsewhere installers
|
|
20
21
|
compile them, see [when no wheel matches](docs/SUPPORT_WHEELS.md#when-no-wheel-matches).
|
|
22
|
+
CUDA rendering is unavailable on macOS.
|
|
21
23
|
|
|
22
24
|
## Visualize a tensor
|
|
23
25
|
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# Building an app
|
|
2
|
+
|
|
3
|
+
Install the framework into the same environment that runs the app. Both the
|
|
4
|
+
package name and import name are `meltygui`. There is no `src` package and no
|
|
5
|
+
requirement to launch from the framework checkout.
|
|
6
|
+
|
|
7
|
+
When contributing reusable features to the library, also follow the
|
|
8
|
+
[ownership and render-function contracts](../CONTRIBUTING.md).
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
import meltygui
|
|
12
|
+
from meltygui.core.core_render import render_func
|
|
13
|
+
from meltygui.core.conversion.dict_conversion import DictConversion
|
|
14
|
+
|
|
15
|
+
class EditorState(DictConversion):
|
|
16
|
+
def __init__(self):
|
|
17
|
+
super().__init__()
|
|
18
|
+
self.text = "Hello"
|
|
19
|
+
|
|
20
|
+
@meltygui.glfw_window(name="Editor", app_id="my-editor", width=900, height=700)
|
|
21
|
+
@render_func(use_cache=False)
|
|
22
|
+
def editor(input_value=None, state: EditorState = None):
|
|
23
|
+
changed, state.text = meltygui.draw_text(state.text)
|
|
24
|
+
return changed, input_value
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The loop starts after the main module finishes defining its windows.
|
|
28
|
+
Injected state persists across frames and sessions. Call render functions every
|
|
29
|
+
frame, returning `(changed, value)`. For nested windows, pass `closable=True` and
|
|
30
|
+
an `open_requested` event to the same call every frame. Use `glfw_window=True` to
|
|
31
|
+
host a child in a native window; its lifecycle follows the same rules.
|
|
32
|
+
|
|
33
|
+
Closed, event-opened dialogs may skip the renderer call entirely. Inject a
|
|
34
|
+
`WindowCallState` from `meltygui.core.windowing.window_visibility`, guard with
|
|
35
|
+
`dialog.needs_call(open_requested)`, and call `dialog.draw(draw_renderer, value,
|
|
36
|
+
open_requested=open_requested, ...)` inside the guard. The state keeps active
|
|
37
|
+
windows receiving lifecycle calls and consumes deferred results even when a
|
|
38
|
+
selection closes the window. Put default-value lookups inside the guard too.
|
|
39
|
+
The guard's handles are runtime-only; the renderer still owns its saved state.
|
|
40
|
+
|
|
41
|
+
### Window size and position: `initial=`, never `width=` / `height=`
|
|
42
|
+
|
|
43
|
+
`width=`, `height=` and `window_pos=` on a call are applied **every frame**: they
|
|
44
|
+
pin the window, so the user cannot resize or move it and the persisted geometry
|
|
45
|
+
is thrown away. To give a window a starting size or place, pass
|
|
46
|
+
`initial={...}`; it is written once, on the window's first frame, and the user's
|
|
47
|
+
(persisted) geometry wins afterwards:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
draw_dep_manager(value, name="Dependencies", closable=True, as_window=True,
|
|
51
|
+
open_requested=clicked,
|
|
52
|
+
initial={"width": 760, "height": 620, "window_pos": (240, 90)})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`initial` also works at decorator level (`window(initial={...})`); a caller's
|
|
56
|
+
`initial` wins over the decorator's. Pass `width=` / `height=` only to views laid
|
|
57
|
+
out by their parent (a tile, a cell, a button), where the parent owns the size.
|
|
58
|
+
|
|
59
|
+
## Live backgrounds and overlays on cached views
|
|
60
|
+
|
|
61
|
+
Use `@render_func(draw_background=paint_backing)` for a lightweight live pass
|
|
62
|
+
beneath a view's body. It receives the same arguments as `draw_overlay`, but
|
|
63
|
+
its `draw_list` is the window's body list, before cached pixels and shadows.
|
|
64
|
+
It runs on normal draws, cache hits, and frozen resize replay. A cached
|
|
65
|
+
ancestor first places its children, then repaints their backgrounds and
|
|
66
|
+
resident body pixels in parent-first order. `draw_background` replaces the
|
|
67
|
+
wrapper's usual `show_bg` painting; callbacks normally return `None`, or may
|
|
68
|
+
return `(False, bg_color)` to supply the background-color stack for children.
|
|
69
|
+
|
|
70
|
+
`draw_text` uses the reusable `paint_view_background` callback, which honors
|
|
71
|
+
`show_bg`, the view's tint/style and live bounds. Background drawing does not
|
|
72
|
+
rerun the text layout. The current pixel cache still captures composited
|
|
73
|
+
background and body pixels: this pass fills live bounds, including newly
|
|
74
|
+
exposed space, but cannot recolor underneath an existing snapshot. Style edits
|
|
75
|
+
use normal invalidation, and edits to a background callback invalidate its
|
|
76
|
+
associated tiles. Use the foreground hook for uncaptured animated decoration.
|
|
77
|
+
A descendant needs its own cached body for this independent replay; an
|
|
78
|
+
uncached child flattened into a cached ancestor keeps that ancestor's pixels
|
|
79
|
+
until the ancestor draws again, so its background cannot erase its text.
|
|
80
|
+
|
|
81
|
+
Pass a plain callable as `@render_func(draw_overlay=draw_status)` or as a
|
|
82
|
+
per-call `draw_overlay=` override. It runs after the body on each rendered
|
|
83
|
+
frame, including blit hits, layout-owned child texture replay during frozen
|
|
84
|
+
resize, and cached ancestors. Uncached
|
|
85
|
+
views support the same callback. Normal idle-window sleeping still applies.
|
|
86
|
+
|
|
87
|
+
Framework scrollbars use this same path for every view, with or without
|
|
88
|
+
caching or freeze resize. They are never baked into tile textures. Cached
|
|
89
|
+
ancestors retain descendant scrollbar owners alongside custom overlays, so
|
|
90
|
+
live clipping, thumb geometry and drag subscriptions continue during replay.
|
|
91
|
+
Scrollbar drag input still uses the normal event router; wheel input remains
|
|
92
|
+
in the wrapper. Scroll changes invalidate content through `scroll_offset`.
|
|
93
|
+
|
|
94
|
+
The callback may accept any subset of the keyword arguments `input_value`,
|
|
95
|
+
`draw_state`, and `draw_list`. `input_value` is the current input supplied to
|
|
96
|
+
the view; `draw_state` is its existing state. Draw primitives into the supplied
|
|
97
|
+
`draw_list`, which is clipped and masked behind higher windows. Use
|
|
98
|
+
`draw_state.abs_left` / `abs_top` for cached live screen coordinates. Balance
|
|
99
|
+
any draw-list pushes/pops inside the callback. Use `draw_state.on_action` for
|
|
100
|
+
interactions, as with the built-in scrollbar. Keep ordinary controls and
|
|
101
|
+
`render_func` calls in the body; the overlay itself must not be decorated.
|
|
102
|
+
|
|
103
|
+
When a cached parent owns child layout, use `draw_overlay_background=` to
|
|
104
|
+
place those children with `place_overlay_view` and, when needed, paint their
|
|
105
|
+
resident body pixels with `paint_cached_view`. On replay, background callbacks
|
|
106
|
+
run parent first, before descendant overlays. Foreground `draw_overlay`
|
|
107
|
+
callbacks then run child first, leaving the parent's controls on top. Both
|
|
108
|
+
callbacks accept the same arguments and obey the same budget. Keep expensive
|
|
109
|
+
resource preparation in the body. Private injected state parameters (names
|
|
110
|
+
beginning with `_`) stay local to their view and are excluded from tile links.
|
|
111
|
+
|
|
112
|
+
Lightweight rows can reuse the view-selection appearance with
|
|
113
|
+
`Melty.paint_selection(draw_state, draw_list, (x, y, width, height))` in their
|
|
114
|
+
overlay. Pass live absolute bounds; the painter uses the owning view's tint
|
|
115
|
+
and clip. This avoids a render wrapper per row and keeps selection out of the
|
|
116
|
+
cached body. File listings and project trees share their row-overlay painter.
|
|
117
|
+
|
|
118
|
+
Callbacks must be very lightweight: taking **more than 0.5 ms of render-thread
|
|
119
|
+
CPU time** disables that callback for the view. The budget uses `time.thread_time()`
|
|
120
|
+
so scheduler pauses and work on other threads cannot permanently disable a cheap
|
|
121
|
+
overlay. This excludes waits and is not a wall-clock latency guarantee; blocking
|
|
122
|
+
I/O and resource preparation still belong outside overlays. Exceptions and invalid
|
|
123
|
+
callbacks also draw an error instead. The first slow call must finish before it
|
|
124
|
+
can be measured; its geometry is discarded, and subsequent frames skip it.
|
|
125
|
+
Replacing the callback or hot-swapping its code retries it. Failure state is
|
|
126
|
+
independent per view.
|
|
127
|
+
|
|
128
|
+
See [the runnable overlay example](../examples/render_overlay.py).
|
|
129
|
+
|
|
130
|
+
## Common imports
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from meltygui import draw_text, draw_voxels, glfw_window, imgui
|
|
134
|
+
from meltygui.core.core_render import render_func
|
|
135
|
+
from meltygui.core.rendering.core_decoration import defaults, no_save
|
|
136
|
+
from meltygui.core.conversion.dict_conversion import DictConversion
|
|
137
|
+
from meltygui.core.conversion.render_host import RenderHost
|
|
138
|
+
from meltygui.view.code_view import draw_function_live
|
|
139
|
+
from meltygui.graphics import Filter
|
|
140
|
+
from meltygui.chat import draw_chat_interface, register_chat_backend
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`meltygui.persisted(name, factory, app_id=...)` retains app-owned objects in
|
|
144
|
+
addition to automatically retained view state. Keep an existing app's `app_id`
|
|
145
|
+
when migrating so its session file remains the same.
|
|
146
|
+
|
|
147
|
+
## Settings
|
|
148
|
+
|
|
149
|
+
`@glfw_window(settings=...)` takes a plain dict of defaults and keeps it between
|
|
150
|
+
runs. The dict is loaded in place before the loop starts, so the app reads it
|
|
151
|
+
like any dict; nested dicts are sub-folders of the settings window.
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
SETTINGS = {'font_size': 14, 'editor': {'tab_width': 4, 'wrap': False}}
|
|
155
|
+
|
|
156
|
+
@meltygui.glfw_window(name="Editor", app_id="my-editor", settings=SETTINGS)
|
|
157
|
+
def editor():
|
|
158
|
+
size = SETTINGS['font_size']
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The dict's own values are the schema: a saved value only lands on a key the
|
|
162
|
+
dict has, with the same type, so a renamed or removed setting disappears and a
|
|
163
|
+
new one shows its default. The file is `$XDG_CONFIG_HOME/<app_id>/settings.json`
|
|
164
|
+
(default `~/.config`), one section per window name, written when the settings
|
|
165
|
+
window changes a value and on exit. A window with settings shows a cog in its
|
|
166
|
+
title bar, just inside the window controls, that opens the settings window
|
|
167
|
+
(the dict drawn as a child native window). See `meltygui/examples/settings_demo.py`.
|
|
168
|
+
|
|
169
|
+
## Tiled editors
|
|
170
|
+
|
|
171
|
+
Mark an editor with `@render_func(multi_instance=True)` to offer it in every
|
|
172
|
+
tile's editor dropdown. Registration happens when its module is imported; the
|
|
173
|
+
flag does not open a window. A render function defined elsewhere (a library
|
|
174
|
+
view) registers with `multi_instance(view)`, and keeps its own `display_name` /
|
|
175
|
+
`icon` / `tint` in the picker. A plain callable (no render boundary of its own)
|
|
176
|
+
is offered through the host's `multi_instance_renderers`:
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from meltygui import draw_claude_chat # one call of draw_chat_interface
|
|
180
|
+
draw_tiles(tiles, draw_state, multi_instance_renderers=(draw_claude_chat,))
|
|
181
|
+
```
|
|
182
|
+
A tile calls its editor with `layout_frame` (its
|
|
183
|
+
four edge dicts); an editor that lays out columns forwards it to the view that
|
|
184
|
+
does, as `draw_chat_interface(layout_frame=...)` does, so the columns stay
|
|
185
|
+
inside the tile instead of adopting the window frame. A `Tile` in the app model owns the selected function
|
|
186
|
+
reference and its `input_value`. `Tile` and `Split` are `DictConversion` models,
|
|
187
|
+
so the normal app/session persistence saves the layout and function references.
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
from meltygui.model.tile_model import Split, Tile
|
|
191
|
+
|
|
192
|
+
@render_func(multi_instance=True, tint=(0.2, 0.4, 0.6))
|
|
193
|
+
def draw_scene(input_value: Scene, state: ViewportState = None):
|
|
194
|
+
...
|
|
195
|
+
return changed, input_value
|
|
196
|
+
|
|
197
|
+
# Store this on your app model. A layout always has a Split root.
|
|
198
|
+
app_model.tiles = Split("x", [
|
|
199
|
+
Tile(render_func=draw_scene, input_value=scene),
|
|
200
|
+
Tile(render_func=draw_scene, input_value=scene),
|
|
201
|
+
])
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The host declares `multi_instance_renderers=()` to receive the eligible
|
|
205
|
+
function references from core, and passes that parameter to `draw_tiles` along
|
|
206
|
+
with its injected `TileManagerState`. The selected editor receives the tile's
|
|
207
|
+
input unchanged: the app supplies a compatible value, or the editor accepts
|
|
208
|
+
`None` and uses injected model/state. Choosing another editor does not construct
|
|
209
|
+
or convert model data.
|
|
210
|
+
|
|
211
|
+
Each tile has independent injected view state. Switching editors and switching
|
|
212
|
+
back restores that tile's editor state. Splitting inherits the renderer and
|
|
213
|
+
shares the input value, while creating a new view instance. See
|
|
214
|
+
`examples/tile_manager.py` for a runnable demo with counters and notes.
|
|
215
|
+
|
|
216
|
+
### Sibling state parameters
|
|
217
|
+
|
|
218
|
+
Each consuming tile gets one compact link-icon dropdown beside the tile switcher.
|
|
219
|
+
The menu presents one column per injected parameter, with its name, required type,
|
|
220
|
+
and eligible sources. Columns wrap on narrow displays. Selected rows have an
|
|
221
|
+
outline, stronger fill and a fixed checkmark gutter so labels stay aligned.
|
|
222
|
+
Selections leave the menu open; Escape or a click outside closes it.
|
|
223
|
+
|
|
224
|
+
`[tile switcher] [chain · selected-source icons]`
|
|
225
|
+
|
|
226
|
+
The trigger reserves one icon slot per parameter. Auto shows the resolved source
|
|
227
|
+
icon; missing icons use a chain, and Self contained uses a database. Auto rows
|
|
228
|
+
use a wand icon.
|
|
229
|
+
|
|
230
|
+
Parameters come from the selected function's signature:
|
|
231
|
+
|
|
232
|
+
```python
|
|
233
|
+
from meltygui import DrawState, render_func
|
|
234
|
+
|
|
235
|
+
@render_func()
|
|
236
|
+
def draw_consumer(input_value, source: DrawState[draw_source] = None,
|
|
237
|
+
selection: SelectionState = None):
|
|
238
|
+
...
|
|
239
|
+
return changed, input_value
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
`DrawState[draw_source]` is a runtime framework annotation: `source` receives the
|
|
243
|
+
actual draw state of the selected sibling instance of `draw_source`, or `None`
|
|
244
|
+
when unlinked/unavailable. Declare/import the source function before using it in
|
|
245
|
+
an annotation. The consumer's own `draw_state` parameter is unchanged. A source
|
|
246
|
+
reference exists before either tile renders; geometry and body-produced fields
|
|
247
|
+
reflect its latest render, so a newly created view has no rendered geometry yet.
|
|
248
|
+
This convention is runtime metadata, not a standard static Python generic.
|
|
249
|
+
|
|
250
|
+
A view can set `draw_state.nickname = "My instance"` to identify itself in link
|
|
251
|
+
menus. Nicknames are display metadata: changing one never changes the unique ID,
|
|
252
|
+
cache identity, or saved bindings. Leave it `None` to use the tile name. Source
|
|
253
|
+
rows colour the renderer icon and subtly tint the text using the instance's
|
|
254
|
+
`current_tint`, falling back
|
|
255
|
+
to its renderer/tile tint before its first render. Duplicate nicknames retain a
|
|
256
|
+
tile-ID suffix so distinct instances remain selectable.
|
|
257
|
+
|
|
258
|
+
A `DictConversion` state parameter (default `None`, or without a default) offers
|
|
259
|
+
compatible owned state from siblings. Unlinked state is still created locally
|
|
260
|
+
by core. Linking borrows the source instance without changing its owner or
|
|
261
|
+
replacing the consumer's retained local instance. State sources are the sibling's
|
|
262
|
+
owned instances, not the instances it may itself borrow from another tile.
|
|
263
|
+
|
|
264
|
+
Each parameter column lists **Auto**, eligible sibling sources in the same tile
|
|
265
|
+
tree, then **Self contained** with a database icon. Self contained uses a private
|
|
266
|
+
local state object, or `None` for a view reference. Existing manual and local settings are
|
|
267
|
+
preserved. Auto chooses the source with the fewest parent/child edges through
|
|
268
|
+
the tile tree, not pixel distance, so resizing cannot change its selection.
|
|
269
|
+
Equal distances retain the current eligible source; without one, stable tile ID
|
|
270
|
+
order breaks ties. Auto remains selected when there are no eligible sources and
|
|
271
|
+
uses `None`/local state until a source becomes available. Manual choices stay pinned.
|
|
272
|
+
|
|
273
|
+
Splitting copies the original tile's link settings, including Auto and settings
|
|
274
|
+
for other renderers, into an independent dictionary on the new tile. It also
|
|
275
|
+
inherits Auto's tie preference. The new tile keeps its own local state; editing
|
|
276
|
+
its links does not change the original's links.
|
|
277
|
+
|
|
278
|
+
Bindings persist by renderer, parameter, source tile ID and source parameter.
|
|
279
|
+
Reordering a tile preserves its links. A missing or incompatible source is shown
|
|
280
|
+
as **Source unavailable** and uses `None`/local state until restored or explicitly
|
|
281
|
+
changed. Switching a consumer's renderer preserves that renderer's bindings for
|
|
282
|
+
when it is selected again. Sources belong to the same `draw_tiles` tree; views
|
|
283
|
+
don't need sibling traversal or registration code. Caller-supplied state also
|
|
284
|
+
works outside tiles, including `source=some_draw_state`.
|
|
285
|
+
|
|
286
|
+
Injected objects are cache dependencies: attribute edits invalidate consumers,
|
|
287
|
+
including across cached frames. As elsewhere, report in-place edits with the
|
|
288
|
+
view's `changed` result. See `examples/tile_sibling_links.py` for both annotation
|
|
289
|
+
forms without changing any existing file-tree or editor view.
|
|
290
|
+
|
|
291
|
+
Hosted renderers can declare `instance` and `layout_frame` parameters. These
|
|
292
|
+
receive the tile's existing conversion identity and its four shared frame edges,
|
|
293
|
+
so instance-targeted commands and nested column layouts stay within that tile.
|
|
294
|
+
An editor created by a corner split first renders when the drag ends, after its
|
|
295
|
+
initial size is known.
|
|
296
|
+
|
|
297
|
+
Files in an installed library are read-only to the live editor. App source roots
|
|
298
|
+
are registered from the app's entry point and decorated functions. An editable
|
|
299
|
+
framework checkout can also be edited; an ordinary wheel in site-packages cannot.
|
|
300
|
+
|
|
301
|
+
## Designing a feature
|
|
302
|
+
|
|
303
|
+
**Locality.** Each thing lives next to what it belongs to, at the smallest scope that holds
|
|
304
|
+
all of its users. Apply it to code, state, UI and lifetime, and let structure grow only when a
|
|
305
|
+
second user appears somewhere else:
|
|
306
|
+
|
|
307
|
+
- **Code**: a feature is one file in the app that uses it: its state class, its handful of
|
|
308
|
+
functions and its view together. Move a part into meltygui / meltygui_pro when a second app or
|
|
309
|
+
view needs it, or the package-split rules require it, and say what asked for it.
|
|
310
|
+
- **State and config**: state lives on the thing it describes. View state is one injected
|
|
311
|
+
`DictConversion` per view (`@no_save` for process-lifetime fields); config a user edits lives
|
|
312
|
+
in the project it configures (`[tool.melty.<feature>]` in `pyproject.toml`), read the way the
|
|
313
|
+
app already reads it, in the flattest form that works; machine-local state lives in the
|
|
314
|
+
injected state or the file-meta store. Prefer plain data (`dict`, tuples, strings); add a class,
|
|
315
|
+
registry or service when two things must share it, not because a feature might grow.
|
|
316
|
+
- **UI**: a feature appears beside the things it acts on and takes its context (project, file,
|
|
317
|
+
selection) from those neighbours, the way the app's most recent features do. It is built from
|
|
318
|
+
the widgets already here; menus and chords go in the app's entry module; both backends
|
|
319
|
+
identical.
|
|
320
|
+
- **Lifetime**: what a feature starts (a process, a thread, a watch) belongs to it: stopped
|
|
321
|
+
by its own explicit action and at app exit, never as a side effect of something unrelated.
|
|
322
|
+
Background work is a daemon thread writing plain fields and calling `request_render()`, the
|
|
323
|
+
view invalidating while it runs; heavier machinery only when that pattern cannot do it.
|
|
324
|
+
|
|
325
|
+
Older subsystems grew under different pressures; take proven recipes from them (spawning,
|
|
326
|
+
streaming, waking the UI), not a new feature's shape.
|
|
327
|
+
|
|
328
|
+
**A design doc is a page**: the state fields, the function signatures, the view, the build order,
|
|
329
|
+
and a "later" list. The first version ships the core; extras wait in "later" until someone wants
|
|
330
|
+
them. When a design genuinely needs more than this, say why in a sentence and go ahead.
|
|
331
|
+
|
|
332
|
+
## Native binding imports
|
|
333
|
+
|
|
334
|
+
MeltyGUI uses a namespaced ImGui binding. Low-level app code should use
|
|
335
|
+
`from meltygui import imgui` (or `import meltygui_imgui as imgui`). Mixing contexts from
|
|
336
|
+
upstream `imgui` with MeltyGUI's binding is unsupported. The upstream packages
|
|
337
|
+
can coexist because the support wheels install different Python namespaces.
|
|
338
|
+
|
|
339
|
+
The optional tensor backend similarly uses `meltygui_pycuda`. A child project's
|
|
340
|
+
own `pycuda` dependency remains independent of MeltyGUI's internal backend.
|
|
@@ -7,16 +7,25 @@ remaining migration work and deliberate deferrals.
|
|
|
7
7
|
|
|
8
8
|
## Setup
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
Linux x86-64 uses CPython 3.11, 3.12 or 3.13 and OpenGL 4.3. macOS on Apple
|
|
11
|
+
Silicon is tested with CPython 3.12 and Apple's OpenGL 4.1 core context,
|
|
12
|
+
including Retina font atlases and cached tiles. CUDA rendering requires an
|
|
13
|
+
NVIDIA system and is unavailable on macOS.
|
|
14
|
+
|
|
15
|
+
MeltyGUI itself is not on PyPI yet, so install it from a checkout. Native
|
|
16
|
+
support packages come from PyPI; `meltygui-imgui` builds from source on macOS
|
|
17
|
+
when no matching wheel is available, using Xcode Command Line Tools:
|
|
14
18
|
|
|
15
19
|
```sh
|
|
16
20
|
uv venv --python 3.12
|
|
17
21
|
uv pip install --python .venv/bin/python -e . --group dev
|
|
18
22
|
```
|
|
19
23
|
|
|
24
|
+
On macOS, install `uv` with `brew install uv` if needed. Install Xcode Command
|
|
25
|
+
Line Tools with `xcode-select --install` if they are not already available.
|
|
26
|
+
The first native ImGui build can take a few minutes. No local `dist/release`
|
|
27
|
+
directory is required.
|
|
28
|
+
|
|
20
29
|
To use MeltyGUI from another project, add the checkout as a path dependency:
|
|
21
30
|
|
|
22
31
|
```sh
|
|
@@ -65,18 +74,43 @@ python3 tools/torch_matrix.py --window-smoke # also opens the README example:
|
|
|
65
74
|
Run apps with the environment's Python. The native Wayland and GLFW backends
|
|
66
75
|
share the same render functions.
|
|
67
76
|
|
|
77
|
+
macOS native resizing redraws through GLFW's window-refresh callback while
|
|
78
|
+
Cocoa holds the event loop. The app only permits those frames during its OS
|
|
79
|
+
event dispatch, restores the interrupted window's graphics contexts, and
|
|
80
|
+
defers recursive refreshes and native window creation/destruction to the loop.
|
|
81
|
+
When checking this path, drag the actual window border: programmatic size
|
|
82
|
+
changes alone do not exercise Cocoa's live-resize loop.
|
|
83
|
+
|
|
68
84
|
```sh
|
|
69
85
|
.venv/bin/pytest
|
|
70
86
|
.venv/bin/python examples/tensor_live.py
|
|
71
87
|
.venv/bin/python examples/voxel_playground.py
|
|
72
88
|
```
|
|
73
89
|
|
|
74
|
-
Use `MELTY_BENCH=1` for a first-frame smoke run
|
|
90
|
+
Use `MELTY_BENCH=1` for a first-frame smoke run; it prints the start-up
|
|
91
|
+
phase table (also appended to `~/.cache/<app_id>/startup.log` on every launch)
|
|
92
|
+
and exits after the first frame:
|
|
75
93
|
|
|
76
94
|
```sh
|
|
77
95
|
MELTY_BENCH=1 .venv/bin/python examples/tensor_live.py
|
|
78
96
|
```
|
|
79
97
|
|
|
98
|
+
### Start-up
|
|
99
|
+
|
|
100
|
+
The boot sequence is described at the top of `meltygui/core/runtime/app.py`
|
|
101
|
+
and in the `meltygui` package docstring. An app's own imports run before its
|
|
102
|
+
first `@glfw_window`; that decoration starts an import thread (the render
|
|
103
|
+
libraries — imgui, numpy, OpenGL — and the GL side of the runtime) and opens
|
|
104
|
+
the display on the calling thread, so the two overlap. The overlap is only real
|
|
105
|
+
while the render graph stays light: `meltygui`, `core_render` and the views
|
|
106
|
+
must not import the render libraries or the code-editing stack (libcst) at
|
|
107
|
+
module level. The code stack loads with the first code edit — the inputs tab,
|
|
108
|
+
a code view, a hotswap. `tests/test_startup_imports.py` pins this; when a
|
|
109
|
+
change makes it fail, move the import into the function that needs it or,
|
|
110
|
+
for a renderer of a code-stack type, register it by name
|
|
111
|
+
(`is_default_for='CodeLine'`). Start-up workers belong in
|
|
112
|
+
`meltygui.after_first_frame(fn)`, not in the first frame.
|
|
113
|
+
|
|
80
114
|
Smoke-run every README example the same way (opens windows; run it from a
|
|
81
115
|
reserved agent desktop):
|
|
82
116
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Input recording and replay
|
|
2
|
+
|
|
3
|
+
Record what a user did in a MeltyGUI app; replay it against a fresh instance from
|
|
4
|
+
outside, through the `hyprland-desktop` MCP server. Recording needs only
|
|
5
|
+
MeltyGUI. Replay needs the MCP server and is run by melty-admin. This replaces new work on the Orchestrator, which
|
|
6
|
+
stays in place and untouched.
|
|
7
|
+
|
|
8
|
+
## Record
|
|
9
|
+
|
|
10
|
+
| How | When |
|
|
11
|
+
|---|---|
|
|
12
|
+
| `MELTY_RECORD_INPUT=1` (or `=/path/file.input.jsonl`) | one launch, from the first frame |
|
|
13
|
+
| `Toggles.InputRecording.record_on_launch = True` | every launch: crash reproduction, analytics |
|
|
14
|
+
| the **Input Recorder** window's Record / Stop | a span inside a session; the Stop click is left out |
|
|
15
|
+
| `draw_input_recorder(Melty.input_recorder)` | the same view inside your own app |
|
|
16
|
+
|
|
17
|
+
Files land in `~/.cache/meltygui/input_recordings/` (newest
|
|
18
|
+
`Toggles.InputRecording.keep_recordings` kept). A file is JSON lines, flushed as
|
|
19
|
+
it is written, so the session that crashed is on disk up to the crash; the
|
|
20
|
+
format is documented at the top of
|
|
21
|
+
[input_recording_model.py](../meltygui/model/input_recording_model.py).
|
|
22
|
+
`Toggles.InputRecording.record_typed_text = False` keeps typed text out.
|
|
23
|
+
|
|
24
|
+
## Replay
|
|
25
|
+
|
|
26
|
+
The front end is melty-admin's **Integration Tests** page and runner
|
|
27
|
+
(`melty-admin/docs/INTEGRATION_TESTS.md`): **Record** there opens the editor on
|
|
28
|
+
fresh state with `MELTY_RECORD_INPUT` set, and the session becomes the case
|
|
29
|
+
`recording.<name>`, replayed on a reserved agent desktop with the suite's
|
|
30
|
+
isolation, video and run history. MeltyGUI's part is knowing the recording:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from meltygui.model.input_recording_model import InputRecording, compile_steps
|
|
34
|
+
from meltygui.core.automation.input_replay import replay_steps
|
|
35
|
+
recording = InputRecording.load(path)
|
|
36
|
+
result = await replay_steps(desktop, compile_steps(recording.events), recording.windows())
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`desktop` is any transport with `find_window(title)` and `call(tool, **arguments)`
|
|
40
|
+
(the module docstring has the contract; melty-admin's is
|
|
41
|
+
`melty_integration/recorded.py`). `python -m meltygui.core.automation.input_replay
|
|
42
|
+
RECORDING` prints the compiled steps and needs no server.
|
|
43
|
+
|
|
44
|
+
A replay only reproduces a session that starts where the recording started:
|
|
45
|
+
launch both on the same document with empty `XDG_STATE_HOME`, `XDG_CACHE_HOME`,
|
|
46
|
+
`XDG_CONFIG_HOME` and `XDG_DATA_HOME`, which is what the page's Record does.
|
|
47
|
+
|
|
48
|
+
How a step is made reliable: each OS window is found by its title and resized to
|
|
49
|
+
the recorded content size; a click on a control that published its text
|
|
50
|
+
(`Melty.effect_hook("button", ..., text=label)`: `flat_button`, `draw_button`)
|
|
51
|
+
is placed by OCR within 120 px of the recorded point, and falls back to the
|
|
52
|
+
recorded point when OCR cannot read it. Everything else replays by coordinate.
|
|
53
|
+
|
|
54
|
+
## Where the code lives
|
|
55
|
+
|
|
56
|
+
| File | Owns |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `core/input/input_handler.py` | `add_input_observer`: passive listeners on the one input funnel |
|
|
59
|
+
| `core/melty.py` | `Melty.input_recorder`; `Melty.effect_hook` fans out to `effect_listeners` |
|
|
60
|
+
| `model/input_recording_model.py` | `InputRecorder` (queue + writer thread), `InputRecording`, `compile_steps` (pure) |
|
|
61
|
+
| `view/input_recording_view.py` | `draw_input_recorder(input_value: InputRecorder)` |
|
|
62
|
+
| `core/automation/input_recording_core.py` | wiring: window probe, Toggles, record on launch, window registration |
|
|
63
|
+
| `core/automation/input_replay.py` | recording -> MCP `batch` steps, sent over any transport; never imported by the app |
|
|
64
|
+
|
|
65
|
+
## Frame cost
|
|
66
|
+
|
|
67
|
+
The observer list is empty unless a recording runs: idle cost is one truthiness
|
|
68
|
+
check per input event (0.09 µs). While recording, an event costs a tuple and a
|
|
69
|
+
`SimpleQueue.put` on the input callback (1.0 µs measured, with at most one cursor
|
|
70
|
+
sample per frame: about 0.01 % of the 8.3 ms budget); JSON encoding and file
|
|
71
|
+
writes happen on the writer thread. Replay and OCR run in another process.
|
|
72
|
+
|
|
73
|
+
## Known limits
|
|
74
|
+
|
|
75
|
+
- Bare cursor travel is not replayed, so hover-only UI (tooltips, hover menus)
|
|
76
|
+
is not reproduced. Space-mouse axes are not recorded.
|
|
77
|
+
- Replay coordinates assume the compositor's window geometry is the content
|
|
78
|
+
(true for the native Wayland backend, verified). The GLFW backend is unverified.
|
|
79
|
+
- One MCP wheel notch is 1.5 scroll units here (`SCROLL_UNITS_PER_NOTCH`).
|
|
80
|
+
- A replay reports only whether every step ran; the end state is for the
|
|
81
|
+
test (or the video) to judge.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Publishing
|
|
1
|
+
# Publishing a release
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`meltygui` 0.1.0 was published on 2026-09-18 through the workflow below.
|
|
4
4
|
|
|
5
5
|
## Required account decisions
|
|
6
6
|
|
|
@@ -43,6 +43,27 @@ entire `dist` tree. The latter also contains older experimental artifacts.
|
|
|
43
43
|
`SHA256.json` records the intended uploads. Never reuse a published version for
|
|
44
44
|
changed files; bump the relevant core or support-package version.
|
|
45
45
|
|
|
46
|
+
### From Thermostat
|
|
47
|
+
|
|
48
|
+
The top **Deployment checklist** has **Prepare deployment** and **Deploy**. Preparation synchronizes
|
|
49
|
+
all three package versions and MeltyGUI's native requirements, optionally commits/pushes the release
|
|
50
|
+
edits, verifies native builds, and runs MeltyGUI's installation tests with support wheels.
|
|
51
|
+
Existing changes must first be reviewed and pushed. Deploy rechecks the tested source commits and
|
|
52
|
+
publishes ImGui, PyCUDA, then MeltyGUI, waiting for each native release to reach PyPI.
|
|
53
|
+
The `imgui_run_id` and `pycuda_run_id` workflow inputs identify successful native builds. During
|
|
54
|
+
verification, their public source commits are checked out and rebuilt into staged wheels; this needs
|
|
55
|
+
no credential for cross-repository artifact downloads. Already published native releases and all
|
|
56
|
+
publication runs install support wheels from PyPI. GPU execution still needs separate hardware validation.
|
|
57
|
+
|
|
58
|
+
Individual controls remain available:
|
|
59
|
+
|
|
60
|
+
Use Deployments → **Raise version** when needed → **Review / commit / push** →
|
|
61
|
+
**Verify build** → **Publish**. The review button opens the repository's Version
|
|
62
|
+
Control card. The UI distinguishes failed, unverified and verified source;
|
|
63
|
+
confirmations carry the displayed version and source commit. The workflow's
|
|
64
|
+
optional `expected_version` and `expected_sha` inputs validate that version and
|
|
65
|
+
pin checkout to the confirmed source. Manual GitHub runs may leave both blank.
|
|
66
|
+
|
|
46
67
|
## Acceptance after upload
|
|
47
68
|
|
|
48
69
|
Use a new environment for each supported Python (3.11, 3.12, 3.13) with no local find-links or extra index:
|
|
@@ -55,4 +76,4 @@ uv pip install --python /tmp/meltygui-from-pypi/bin/python meltygui
|
|
|
55
76
|
|
|
56
77
|
Then launch a child app and check `meltygui[tensor]` on a supported NVIDIA machine.
|
|
57
78
|
A local install using `--find-links` validates the artifacts, not public PyPI
|
|
58
|
-
availability.
|
|
79
|
+
availability. 0.1.0 passed the fresh-install check on Linux (3.11-3.13) and Windows (3.12).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""A live overlay on a frozen blit tile. Resize the window to try it."""
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
import meltygui
|
|
5
|
+
from meltygui import imgui, render_func
|
|
6
|
+
from meltygui.core.runtime.toggles import Tint
|
|
7
|
+
from meltygui.core.windowing.glfw_utils import request_render
|
|
8
|
+
from meltygui.hdr_color import pack_color
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def draw_clock(draw_state, draw_list):
|
|
12
|
+
# Use live geometry and the supplied list: neither this text nor its
|
|
13
|
+
# changing position is captured in the body's tile.
|
|
14
|
+
x = draw_state._abs_left() + 12
|
|
15
|
+
y = draw_state._abs_top() + draw_state.header_height + 12
|
|
16
|
+
color = pack_color(*Tint.dd_text(draw_state.current_tint), 1.0)
|
|
17
|
+
draw_list.add_text(x, y, color, f'Live overlay: {time.monotonic():.2f}')
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@render_func(use_cache=True, freeze_resize=True, draw_overlay=draw_clock,
|
|
21
|
+
tint=(0.20, 0.30, 0.42), show_bg=True, auto_resize=False)
|
|
22
|
+
def draw_cached_panel(input_value: str, draw_state=None):
|
|
23
|
+
imgui.get_window_draw_list().add_text(
|
|
24
|
+
draw_state.abs_left + 12, draw_state.abs_top + 70,
|
|
25
|
+
pack_color(*Tint.dd_text(draw_state.current_tint), 1.0), input_value)
|
|
26
|
+
return False, input_value
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@meltygui.glfw_window(name='Render overlays', app_id='meltygui-render-overlay-demo',
|
|
30
|
+
width=720, height=420)
|
|
31
|
+
@render_func(tint=(0.20, 0.30, 0.42), determines_height=False)
|
|
32
|
+
def overlay_demo(input_value: object = None, draw_state=None):
|
|
33
|
+
# A clock animates even without input; ordinary overlays can let the app idle.
|
|
34
|
+
request_render()
|
|
35
|
+
return draw_cached_panel('This body is cached. The clock draws every frame.',
|
|
36
|
+
width=draw_state.width, height=draw_state.height)
|