railmux 0.3.2.dev4__tar.gz → 0.3.2.dev5__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.
- {railmux-0.3.2.dev4/src/railmux.egg-info → railmux-0.3.2.dev5}/PKG-INFO +1 -1
- railmux-0.3.2.dev5/src/railmux/__init__.py +1 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/tmux_binding_manager.py +106 -3
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/tmux_ctl.py +393 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/app.py +151 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5/src/railmux.egg-info}/PKG-INFO +1 -1
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux.egg-info/SOURCES.txt +1 -0
- railmux-0.3.2.dev5/tests/test_termux_local_touch.py +120 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_tmux_binding_manager.py +81 -4
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_tmux_ctl.py +121 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_tmux_integration.py +150 -0
- railmux-0.3.2.dev4/src/railmux/__init__.py +0 -1
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/LICENSE +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/MANIFEST.in +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/README.md +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/pyproject.toml +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/setup.cfg +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/__main__.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/atomic_file.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/background_index.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/cli.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/codex_index.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/config.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/config_cli.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/diagnostics.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/discovery.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/display_transport.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/fast_display_client.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/fast_display_history.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/fast_display_input.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/fast_display_protocol.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/fast_display_server.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/favorites.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/fuzzy.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/help_workspace.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/launcher.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/legacy_sessions.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/local_clipboard.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/local_open.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/models.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/modes.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/mouse_manager.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/mux/__init__.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/mux/backend.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/mux/tmux_backend.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/orphan_marker.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/pane_surface.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/path_codec.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/platform/__init__.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/platform/config_paths.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/platform/console.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/platform/file_security.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/platform/filelock.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/platform/multiplex.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/platform/process.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/platform/runtime_paths.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/remote_config.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/renames.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/restart_state.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/runtime_config.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/scroll_agent.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/scroll_manager.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/selection_isolation.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/self_update.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/session_cache.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/session_index.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/setting_contracts.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/settings.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ssh_args.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ssh_compat.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ssh_display_diagnostics.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ssh_doctor.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/system_deps.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/terminal_emulator.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/terminal_status.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/tmux_health.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/tmux_server.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/tool_panes.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/transcript.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/__init__.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/_widgets.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/keymap.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/modals.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/projects_pane.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/running_pane.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/sessions_pane.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/sidebar.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/statusbar.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/ui/workspace.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/winlocal/__init__.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/winlocal/backend.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/winlocal/client.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/winlocal/compositor.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/winlocal/conpty.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/winlocal/daemon.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/winlocal/history_viewer.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/winlocal/ipc.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/winlocal/session_store.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux/winlocal/virtual_screen.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux.egg-info/dependency_links.txt +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux.egg-info/entry_points.txt +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux.egg-info/requires.txt +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/src/railmux.egg-info/top_level.txt +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_agent_workspace.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_atomic_file.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_background_index.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_cli.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_codex_delete.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_codex_index.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_codex_lineage.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_codex_transcript.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_config.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_config_cli.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_denested_transport_benchmark.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_diagnostics.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_discovery.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_display_transport.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_fast_full_window.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_focus_highlight.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_fullscreen_binding.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_fuzzy.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_help_agent.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_help_workspace.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_history_cleanup.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_keymap.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_launcher.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_layout_profile.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_legacy_sessions.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_local_clipboard.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_local_open.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_modals.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_mode_selection.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_modes.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_mouse_manager.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_mux_backend.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_new_project.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_options.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_orphan_recovery.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_pane_surface.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_path_codec.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_platform.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_projects_pane.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_release_notes.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_release_workflow.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_remote_config.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_renames.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_restart_state.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_running_pane.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_running_sort.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_runtime_config.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_scroll_agent.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_scroll_manager.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_selection_isolation.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_self_update.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_session_cache.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_session_index.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_sessions_pane.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_setting_contracts.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_settings.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_sidebar.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_soft_quit.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_ssh_args.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_ssh_compat.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_ssh_display_benchmark.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_ssh_display_diagnostics.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_ssh_doctor.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_status.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_statusbar.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_system_deps.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_terminal_size.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_terminal_status.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_tmux_health.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_tmux_server.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_tmux_status.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_tool_panes.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_transcript.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_web_demo_recorder.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_wheel_smoke.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_widgets.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_winlocal_backend.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_winlocal_compositor.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_winlocal_conpty.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_winlocal_daemon.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_winlocal_history_viewer.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_winlocal_ipc.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_winlocal_real_conpty.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_winlocal_session_store.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_winlocal_virtual_screen.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tests/test_yolo_prompt.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tools/denested_transport_benchmark.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tools/release_notes.py +0 -0
- {railmux-0.3.2.dev4 → railmux-0.3.2.dev5}/tools/wheel_smoke.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.2.dev5"
|
|
@@ -14,7 +14,7 @@ from railmux.atomic_file import atomic_write_text
|
|
|
14
14
|
from railmux.platform.filelock import try_lock, unlock
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
_VERSION =
|
|
17
|
+
_VERSION = 8
|
|
18
18
|
_KEYS = ("F8", "F9")
|
|
19
19
|
_MAX_STATE_BYTES = 64 * 1024
|
|
20
20
|
|
|
@@ -34,6 +34,7 @@ class SharedTmuxBindingManager:
|
|
|
34
34
|
self._prefix_tab_managed = False
|
|
35
35
|
self._right_click_managed = False
|
|
36
36
|
self._status_click_managed = False
|
|
37
|
+
self._termux_tap_managed = False
|
|
37
38
|
self._selection_hook_managed = False
|
|
38
39
|
self._selection_hook_index: int | None = None
|
|
39
40
|
|
|
@@ -52,6 +53,11 @@ class SharedTmuxBindingManager:
|
|
|
52
53
|
"""Whether pane ranges in this instance's status bar are clickable."""
|
|
53
54
|
return self._registered and self._status_click_managed
|
|
54
55
|
|
|
56
|
+
@property
|
|
57
|
+
def termux_tap_available(self) -> bool:
|
|
58
|
+
"""Whether direct local Termux prompt taps are safely wrapped."""
|
|
59
|
+
return self._registered and self._termux_tap_managed
|
|
60
|
+
|
|
55
61
|
@contextmanager
|
|
56
62
|
def _locked(self) -> Iterator[None]:
|
|
57
63
|
root = restart_state.runtime_state_dir()
|
|
@@ -84,7 +90,7 @@ class SharedTmuxBindingManager:
|
|
|
84
90
|
except (OSError, ValueError, json.JSONDecodeError):
|
|
85
91
|
return None
|
|
86
92
|
if (not isinstance(raw, dict)
|
|
87
|
-
or raw.get("version") not in {1, 2, 3, 4, 5, 6, _VERSION}):
|
|
93
|
+
or raw.get("version") not in {1, 2, 3, 4, 5, 6, 7, _VERSION}):
|
|
88
94
|
return None
|
|
89
95
|
token = raw.get("token")
|
|
90
96
|
phase = raw.get("phase")
|
|
@@ -96,6 +102,8 @@ class SharedTmuxBindingManager:
|
|
|
96
102
|
right_click_managed = raw.get("right_click_managed")
|
|
97
103
|
status_click_backup = raw.get("status_click_backup")
|
|
98
104
|
status_click_managed = raw.get("status_click_managed")
|
|
105
|
+
termux_tap_backup = raw.get("termux_tap_backup")
|
|
106
|
+
termux_tap_managed = raw.get("termux_tap_managed")
|
|
99
107
|
selection_hook_managed = raw.get("selection_hook_managed")
|
|
100
108
|
selection_hook_index = raw.get("selection_hook_index")
|
|
101
109
|
prefix_valid = (
|
|
@@ -116,6 +124,12 @@ class SharedTmuxBindingManager:
|
|
|
116
124
|
and all(value is None or isinstance(value, str)
|
|
117
125
|
for value in status_click_backup.values())
|
|
118
126
|
)
|
|
127
|
+
termux_tap_valid = (
|
|
128
|
+
isinstance(termux_tap_backup, dict)
|
|
129
|
+
and set(termux_tap_backup) == {"MouseDown1Pane"}
|
|
130
|
+
and all(value is None or isinstance(value, str)
|
|
131
|
+
for value in termux_tap_backup.values())
|
|
132
|
+
)
|
|
119
133
|
if (not isinstance(token, str) or not token or len(token) > 64
|
|
120
134
|
or phase not in {"installing", "active"}
|
|
121
135
|
or not isinstance(owners, dict) or len(owners) > 1024
|
|
@@ -140,7 +154,10 @@ class SharedTmuxBindingManager:
|
|
|
140
154
|
and selection_hook_index is not None)))
|
|
141
155
|
or (raw["version"] >= 5
|
|
142
156
|
and (not status_click_valid
|
|
143
|
-
or not isinstance(status_click_managed, bool)))
|
|
157
|
+
or not isinstance(status_click_managed, bool)))
|
|
158
|
+
or (raw["version"] >= 8
|
|
159
|
+
and (not termux_tap_valid
|
|
160
|
+
or not isinstance(termux_tap_managed, bool)))):
|
|
144
161
|
return None
|
|
145
162
|
return raw
|
|
146
163
|
|
|
@@ -265,6 +282,21 @@ class SharedTmuxBindingManager:
|
|
|
265
282
|
# v7 replaces Mode/Layout's ordinary m/F8 keystrokes
|
|
266
283
|
# with edit- and modal-safe internal function keys.
|
|
267
284
|
upgraded = True
|
|
285
|
+
if state["version"] < 8:
|
|
286
|
+
termux_tap_backup = (
|
|
287
|
+
tmux_ctl.prepare_root_termux_tap_binding()
|
|
288
|
+
)
|
|
289
|
+
# v8 adds a stock-left-click-only Termux prompt
|
|
290
|
+
# handoff. Persist its exact original before the
|
|
291
|
+
# server-global root-table binding is replaced.
|
|
292
|
+
state["termux_tap_managed"] = (
|
|
293
|
+
termux_tap_backup is not None
|
|
294
|
+
)
|
|
295
|
+
state["termux_tap_backup"] = (
|
|
296
|
+
termux_tap_backup
|
|
297
|
+
or {"MouseDown1Pane": None}
|
|
298
|
+
)
|
|
299
|
+
upgraded = True
|
|
268
300
|
if upgraded:
|
|
269
301
|
state["version"] = _VERSION
|
|
270
302
|
state["phase"] = "installing"
|
|
@@ -325,6 +357,21 @@ class SharedTmuxBindingManager:
|
|
|
325
357
|
token,
|
|
326
358
|
)
|
|
327
359
|
)
|
|
360
|
+
if state["termux_tap_managed"]:
|
|
361
|
+
current_tap = (
|
|
362
|
+
tmux_ctl.read_root_termux_tap_binding()
|
|
363
|
+
["MouseDown1Pane"]
|
|
364
|
+
)
|
|
365
|
+
safe = (
|
|
366
|
+
safe
|
|
367
|
+
and tmux_ctl.root_termux_tap_binding_is_original_or_owned(
|
|
368
|
+
current_tap,
|
|
369
|
+
state["termux_tap_backup"].get(
|
|
370
|
+
"MouseDown1Pane"
|
|
371
|
+
),
|
|
372
|
+
token,
|
|
373
|
+
)
|
|
374
|
+
)
|
|
328
375
|
if not safe:
|
|
329
376
|
if state["owners"]:
|
|
330
377
|
return False
|
|
@@ -342,6 +389,9 @@ class SharedTmuxBindingManager:
|
|
|
342
389
|
if state["status_click_managed"]:
|
|
343
390
|
tmux_ctl.restore_root_status_click_binding(
|
|
344
391
|
state["status_click_backup"], token=token)
|
|
392
|
+
if state["termux_tap_managed"]:
|
|
393
|
+
tmux_ctl.restore_root_termux_tap_binding(
|
|
394
|
+
state["termux_tap_backup"], token=token)
|
|
345
395
|
self._remove_state()
|
|
346
396
|
state = None
|
|
347
397
|
else:
|
|
@@ -381,6 +431,14 @@ class SharedTmuxBindingManager:
|
|
|
381
431
|
state["status_click_managed"] = False
|
|
382
432
|
if not self._save(state):
|
|
383
433
|
return False
|
|
434
|
+
if (state["termux_tap_managed"]
|
|
435
|
+
and not tmux_ctl.set_root_termux_tap_forwarding(
|
|
436
|
+
state["termux_tap_backup"], token)):
|
|
437
|
+
tmux_ctl.restore_root_termux_tap_binding(
|
|
438
|
+
state["termux_tap_backup"], token=token)
|
|
439
|
+
state["termux_tap_managed"] = False
|
|
440
|
+
if not self._save(state):
|
|
441
|
+
return False
|
|
384
442
|
state["phase"] = "active"
|
|
385
443
|
elif not (
|
|
386
444
|
tmux_ctl.root_function_bindings_owned_by(token)
|
|
@@ -402,6 +460,10 @@ class SharedTmuxBindingManager:
|
|
|
402
460
|
or tmux_ctl.root_status_click_binding_owned_by(
|
|
403
461
|
token)
|
|
404
462
|
)
|
|
463
|
+
and (
|
|
464
|
+
not state["termux_tap_managed"]
|
|
465
|
+
or tmux_ctl.root_termux_tap_binding_owned_by(token)
|
|
466
|
+
)
|
|
405
467
|
):
|
|
406
468
|
if state["owners"]:
|
|
407
469
|
return False
|
|
@@ -419,6 +481,9 @@ class SharedTmuxBindingManager:
|
|
|
419
481
|
if state["status_click_managed"]:
|
|
420
482
|
tmux_ctl.restore_root_status_click_binding(
|
|
421
483
|
state["status_click_backup"], token=token)
|
|
484
|
+
if state["termux_tap_managed"]:
|
|
485
|
+
tmux_ctl.restore_root_termux_tap_binding(
|
|
486
|
+
state["termux_tap_backup"], token=token)
|
|
422
487
|
self._remove_state()
|
|
423
488
|
state = None
|
|
424
489
|
if state is not None:
|
|
@@ -451,6 +516,8 @@ class SharedTmuxBindingManager:
|
|
|
451
516
|
state["selection_hook_index"])
|
|
452
517
|
self._status_click_managed = (
|
|
453
518
|
state["status_click_managed"])
|
|
519
|
+
self._termux_tap_managed = (
|
|
520
|
+
state["termux_tap_managed"])
|
|
454
521
|
return True
|
|
455
522
|
|
|
456
523
|
backup = tmux_ctl.prepare_root_function_bindings()
|
|
@@ -460,6 +527,8 @@ class SharedTmuxBindingManager:
|
|
|
460
527
|
selection_hook_index = tmux_ctl.prepare_selection_mode_hook()
|
|
461
528
|
status_click_backup = (
|
|
462
529
|
tmux_ctl.prepare_root_status_click_binding())
|
|
530
|
+
termux_tap_backup = (
|
|
531
|
+
tmux_ctl.prepare_root_termux_tap_binding())
|
|
463
532
|
if backup is None:
|
|
464
533
|
return False
|
|
465
534
|
token = secrets.token_hex(8)
|
|
@@ -479,6 +548,9 @@ class SharedTmuxBindingManager:
|
|
|
479
548
|
"status_click_managed": status_click_backup is not None,
|
|
480
549
|
"status_click_backup": (
|
|
481
550
|
status_click_backup or {"MouseDown1Status": None}),
|
|
551
|
+
"termux_tap_managed": termux_tap_backup is not None,
|
|
552
|
+
"termux_tap_backup": (
|
|
553
|
+
termux_tap_backup or {"MouseDown1Pane": None}),
|
|
482
554
|
}
|
|
483
555
|
if not self._save(state):
|
|
484
556
|
return False
|
|
@@ -550,6 +622,29 @@ class SharedTmuxBindingManager:
|
|
|
550
622
|
state["selection_hook_index"], token)
|
|
551
623
|
self._remove_state()
|
|
552
624
|
return False
|
|
625
|
+
if (state["termux_tap_managed"]
|
|
626
|
+
and not tmux_ctl.set_root_termux_tap_forwarding(
|
|
627
|
+
state["termux_tap_backup"], token)):
|
|
628
|
+
tmux_ctl.restore_root_termux_tap_binding(
|
|
629
|
+
state["termux_tap_backup"], token=token)
|
|
630
|
+
state["termux_tap_managed"] = False
|
|
631
|
+
if not self._save(state):
|
|
632
|
+
tmux_ctl.restore_root_function_bindings(
|
|
633
|
+
backup, token=token)
|
|
634
|
+
if state["prefix_tab_managed"]:
|
|
635
|
+
tmux_ctl.restore_prefix_target_binding(
|
|
636
|
+
state["prefix_tab_backup"], token=token)
|
|
637
|
+
if state["right_click_managed"]:
|
|
638
|
+
tmux_ctl.restore_root_right_click_binding(
|
|
639
|
+
state["right_click_backup"], token=token)
|
|
640
|
+
if state["selection_hook_managed"]:
|
|
641
|
+
tmux_ctl.restore_selection_mode_hook(
|
|
642
|
+
state["selection_hook_index"], token)
|
|
643
|
+
if state["status_click_managed"]:
|
|
644
|
+
tmux_ctl.restore_root_status_click_binding(
|
|
645
|
+
state["status_click_backup"], token=token)
|
|
646
|
+
self._remove_state()
|
|
647
|
+
return False
|
|
553
648
|
state["phase"] = "active"
|
|
554
649
|
if not self._save(state) or not self._set_controller():
|
|
555
650
|
tmux_ctl.restore_root_function_bindings(
|
|
@@ -566,6 +661,9 @@ class SharedTmuxBindingManager:
|
|
|
566
661
|
if state["status_click_managed"]:
|
|
567
662
|
tmux_ctl.restore_root_status_click_binding(
|
|
568
663
|
state["status_click_backup"], token=token)
|
|
664
|
+
if state["termux_tap_managed"]:
|
|
665
|
+
tmux_ctl.restore_root_termux_tap_binding(
|
|
666
|
+
state["termux_tap_backup"], token=token)
|
|
569
667
|
self._remove_state()
|
|
570
668
|
return False
|
|
571
669
|
self._registered = True
|
|
@@ -574,6 +672,7 @@ class SharedTmuxBindingManager:
|
|
|
574
672
|
self._selection_hook_managed = state["selection_hook_managed"]
|
|
575
673
|
self._selection_hook_index = state["selection_hook_index"]
|
|
576
674
|
self._status_click_managed = state["status_click_managed"]
|
|
675
|
+
self._termux_tap_managed = state["termux_tap_managed"]
|
|
577
676
|
return True
|
|
578
677
|
except OSError:
|
|
579
678
|
return False
|
|
@@ -627,6 +726,9 @@ class SharedTmuxBindingManager:
|
|
|
627
726
|
if state["status_click_managed"]:
|
|
628
727
|
tmux_ctl.restore_root_status_click_binding(
|
|
629
728
|
state["status_click_backup"], token=state["token"])
|
|
729
|
+
if state["termux_tap_managed"]:
|
|
730
|
+
tmux_ctl.restore_root_termux_tap_binding(
|
|
731
|
+
state["termux_tap_backup"], token=state["token"])
|
|
630
732
|
self._remove_state()
|
|
631
733
|
except OSError:
|
|
632
734
|
pass
|
|
@@ -641,5 +743,6 @@ class SharedTmuxBindingManager:
|
|
|
641
743
|
self._prefix_tab_managed = False
|
|
642
744
|
self._right_click_managed = False
|
|
643
745
|
self._status_click_managed = False
|
|
746
|
+
self._termux_tap_managed = False
|
|
644
747
|
self._selection_hook_managed = False
|
|
645
748
|
self._selection_hook_index = None
|