__ __ __ __ _____ _ _ _____ _ _ _ | \/ | \ \ / / | __ \ (_) | | / ____| | | | | | \ / |_ __\ V / | |__) | __ ___ ____ _| |_ ___ | (___ | |__ ___| | | | |\/| | '__|> < | ___/ '__| \ \ / / _` | __/ _ \ \___ \| '_ \ / _ \ | | | | | | |_ / . \ | | | | | |\ V / (_| | || __/ ____) | | | | __/ | | |_| |_|_(_)_/ \_\ |_| |_| |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1 if you need WebShell for Seo everyday contact me on Telegram Telegram Address : @jackleetFor_More_Tools:
# Orca # # Copyright 2024 Igalia, S.L. # Copyright 2024 GNOME Foundation Inc. # Author: Joanmarie Diggs <[email protected]> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., Franklin Street, Fifth Floor, # Boston MA 02110-1301 USA. # pylint: disable=wrong-import-position # pylint: disable=broad-exception-caught # pylint: disable=no-name-in-module """Provides debugging tools.""" # This has to be the first non-docstring line in the module to make linters happy. from __future__ import annotations __id__ = "$Id$" __version__ = "$Revision$" __date__ = "$Date$" __copyright__ = "Copyright (c) 2024 Igalia, S.L." \ "Copyright (c) 2024 GNOME Foundation Inc." __license__ = "LGPL" import faulthandler import os import subprocess import time from typing import Generator, Optional, TYPE_CHECKING import gi gi.require_version("Atspi", "2.0") from gi.repository import Atspi from . import cmdnames from . import debug from . import focus_manager from . import input_event from . import keybindings from . import messages from . import orca_platform from . import settings_manager from .ax_object import AXObject from .ax_utilities import AXUtilities from .ax_utilities_debugging import AXUtilitiesDebugging if TYPE_CHECKING: from .scripts import default class DebuggingToolsManager: """Provides debugging tools.""" def __init__(self) -> None: self._handlers: dict[str, input_event.InputEventHandler] = self.get_handlers(True) self._bindings: keybindings.KeyBindings = keybindings.KeyBindings() if debug.debugFile and os.path.exists(debug.debugFile.name): faulthandler.enable(file=debug.debugFile, all_threads=True) else: faulthandler.enable(all_threads=False) def get_bindings( self, refresh: bool = False, is_desktop: bool = True ) -> keybindings.KeyBindings: """Returns the debugging-tools-manager keybindings.""" if refresh: msg = f"DEBUGGING TOOLS MANAGER: Refreshing bindings. Is desktop: {is_desktop}" debug.print_message(debug.LEVEL_INFO, msg, True) self._setup_bindings() elif self._bindings.is_empty(): self._setup_bindings() return self._bindings def get_handlers(self, refresh: bool = False) -> dict[str, input_event.InputEventHandler]: """Returns the debugging-tools-manager handlers.""" if refresh: msg = "DEBUGGING TOOLS MANAGER: Refreshing handlers." debug.print_message(debug.LEVEL_INFO, msg, True) self._setup_handlers() return self._handlers def _setup_handlers(self) -> None: """Sets up and returns the debugging-tools-manager input event handlers.""" self._handlers = {} self._handlers["cycleDebugLevelHandler"] = \ input_event.InputEventHandler( self._cycle_debug_level, cmdnames.DEBUG_CYCLE_LEVEL) self._handlers["clear_atspi_app_cache"] = \ input_event.InputEventHandler( self._clear_atspi_app_cache, cmdnames.DEBUG_CLEAR_ATSPI_CACHE_FOR_APPLICATION) self._handlers["capture_snapshot"] = \ input_event.InputEventHandler( self._capture_snapshot, cmdnames.DEBUG_CAPTURE_SNAPSHOT) def _setup_bindings(self) -> None: """Sets up and returns the debugging-tools-manager key bindings.""" self._bindings = keybindings.KeyBindings() self._bindings.add( keybindings.KeyBinding( "", keybindings.DEFAULT_MODIFIER_MASK, keybindings.NO_MODIFIER_MASK, self._handlers["cycleDebugLevelHandler"], 1, True)) self._bindings.add( keybindings.KeyBinding( "", keybindings.DEFAULT_MODIFIER_MASK, keybindings.NO_MODIFIER_MASK, self._handlers["clear_atspi_app_cache"], 1, True)) self._bindings.add( keybindings.KeyBinding( "", keybindings.DEFAULT_MODIFIER_MASK, keybindings.NO_MODIFIER_MASK, self._handlers["capture_snapshot"], 1, True)) # This pulls in the user's overrides to alternative keys. self._bindings = settings_manager.get_manager().override_key_bindings( self._handlers, self._bindings, False) def _cycle_debug_level( self, script: default.Script, _event: Optional[input_event.InputEvent] = None ) -> bool: """Cycles through the existing debug levels.""" levels = { debug.LEVEL_ALL: "all", debug.LEVEL_INFO: "info", debug.LEVEL_WARNING: "warning", debug.LEVEL_SEVERE: "severe", debug.LEVEL_OFF: "off", } keys = list(levels.keys()) next_level = keys.index(debug.debugLevel) + 1 if next_level == len(keys): next_level = 0 level = keys[next_level] brief = levels.get(level) debug.debugLevel = level script.presentMessage(f"Debug level {brief}.", brief) return True def _clear_atspi_app_cache( self, script: default.Script, _event: Optional[input_event.InputEvent] = None ) -> bool: """Clears the AT-SPI cache for the current application.""" _mode, obj = focus_manager.get_manager().get_active_mode_and_object_of_interest() if obj is None: msg = "DEBUGGING TOOLS MANAGER: Cannot clear cache on null object of interest." debug.print_message(debug.debugLevel, msg, True) script.presentMessage(messages.DEBUG_CLEAR_CACHE_FAILED) return True app = AXUtilities.get_application(obj) if app is None: msg = "DEBUGGING TOOLS MANAGER: Cannot clear cache on null application." debug.print_message(debug.debugLevel, msg, True) script.presentMessage(messages.DEBUG_CLEAR_CACHE_FAILED) return True script.presentMessage(messages.DEBUG_CLEAR_CACHE) AXObject.clear_cache(app, recursive=True, reason="User request.") return True def _capture_snapshot( self, script: default.Script, _event: Optional[input_event.InputEvent] = None ) -> bool: """Clears the AT-SPI cache for the current application.""" script.presentMessage(messages.DEBUG_CAPTURE_SNAPSHOT_START) old_level = debug.debugLevel debug.debugLevel = debug.LEVEL_SEVERE debug.print_message(debug.debugLevel, "DEBUGGING SNAPSHOT STARTING", True) self.print_running_applications() manager = settings_manager.get_manager() info = AXUtilitiesDebugging.as_string(manager.get_overridden_settings_for_debugging()) msg = f"OVERRIDDEN SETTINGS: {info}" debug.print_message(debug.debugLevel, msg, True) info = AXUtilitiesDebugging.as_string(manager.customized_settings) msg = f"CUSTOMIZED SETTINGS: {info}" debug.print_message(debug.debugLevel, msg, True) debug.print_message(debug.debugLevel, "DEBUGGING SNAPSHOT FINISHED", True) script.presentMessage(messages.DEBUG_CAPTURE_SNAPSHOT_END) debug.debugLevel = old_level return True def _get_running_applications_as_string_iter( self, is_command_line: bool ) -> Generator[str, None, None]: """Generator providing strings with basic details about the running accessible apps.""" applications = AXUtilities.get_all_applications(is_debug=True) msg = f"Desktop has {len(applications)} apps:" if not is_command_line: msg = f"DEBUGGING TOOLS MANAGER: {msg}" yield msg for i, app in enumerate(applications): pid = AXUtilities.get_process_id(app) if AXUtilities.is_application_unresponsive(app): name = "[UNRESPONSIVE]" else: name = AXObject.get_name(app) or "[DEAD]" try: cmdline = subprocess.getoutput(f"cat /proc/{pid}/cmdline") except Exception as error: cmdline = f"EXCEPTION: {error}" else: cmdline = cmdline.replace("\x00", " ") if is_command_line: prefix = f"{time.strftime('%H:%M:%S', time.localtime()):<12}" else: prefix = f"{i+1:3}." msg = f"{prefix} pid: {pid:<10} {name:<25} {cmdline}" yield msg def print_running_applications( self, force: bool = False, is_command_line: bool = False ) -> None: """Prints basic details about the running accessible applications.""" if force: level = debug.LEVEL_SEVERE else: level = debug.LEVEL_INFO if level < debug.debugLevel and not is_command_line: return for app_string in self._get_running_applications_as_string_iter(is_command_line): if is_command_line: print(app_string) else: debug.print_message(level, app_string, True) def print_session_details(self, is_command_line: bool = False) -> None: """Prints basic details about the current session.""" msg = f"Orca version {orca_platform.version}" if orca_platform.revision: msg += f" (rev {orca_platform.revision})" atspi_version = Atspi.get_version() msg += f", AT-SPI2 version: {atspi_version[0]}.{atspi_version[1]}.{atspi_version[2]}" session_type = os.environ.get("XDG_SESSION_TYPE") or "" session_desktop = os.environ.get("XDG_SESSION_DESKTOP") or "" session = f"{session_type} {session_desktop}".strip() if session: msg += f", Session: {session}" if is_command_line: print(msg) else: msg = f"DEBUGGING TOOLS MANAGER: {msg}" debug.print_message(debug.LEVEL_INFO, msg, True) _manager: DebuggingToolsManager = DebuggingToolsManager() def get_manager() -> DebuggingToolsManager: """Returns the debugging tools manager.""" return _manager
| Name | Type | Size | Permission | Actions |
|---|---|---|---|---|
| __pycache__ | Folder | 0755 |
|
|
| backends | Folder | 0755 |
|
|
| scripts | Folder | 0755 |
|
|
| __init__.py | File | 115 B | 0644 |
|
| acss.py | File | 3.85 KB | 0644 |
|
| action_presenter.py | File | 8.65 KB | 0644 |
|
| ax_collection.py | File | 6.16 KB | 0644 |
|
| ax_component.py | File | 14.93 KB | 0644 |
|
| ax_document.py | File | 9.36 KB | 0644 |
|
| ax_event_synthesizer.py | File | 17.39 KB | 0644 |
|
| ax_hypertext.py | File | 8.36 KB | 0644 |
|
| ax_object.py | File | 47.84 KB | 0644 |
|
| ax_selection.py | File | 4.54 KB | 0644 |
|
| ax_table.py | File | 47.98 KB | 0644 |
|
| ax_text.py | File | 45.13 KB | 0644 |
|
| ax_utilities.py | File | 28.24 KB | 0644 |
|
| ax_utilities_application.py | File | 7.17 KB | 0644 |
|
| ax_utilities_collection.py | File | 86.79 KB | 0644 |
|
| ax_utilities_debugging.py | File | 10.12 KB | 0644 |
|
| ax_utilities_event.py | File | 32.78 KB | 0644 |
|
| ax_utilities_relation.py | File | 15.2 KB | 0644 |
|
| ax_utilities_role.py | File | 91.79 KB | 0644 |
|
| ax_utilities_state.py | File | 11.63 KB | 0644 |
|
| ax_value.py | File | 6.83 KB | 0644 |
|
| bookmarks.py | File | 11.95 KB | 0644 |
|
| braille.py | File | 74.03 KB | 0644 |
|
| braille_generator.py | File | 55.79 KB | 0644 |
|
| braille_rolenames.py | File | 10.23 KB | 0644 |
|
| brlmon.py | File | 6.53 KB | 0644 |
|
| brltablenames.py | File | 7.3 KB | 0644 |
|
| bypass_mode_manager.py | File | 4.79 KB | 0644 |
|
| caret_navigation.py | File | 19.51 KB | 0644 |
|
| chat.py | File | 32.03 KB | 0644 |
|
| clipboard.py | File | 20.45 KB | 0644 |
|
| cmdnames.py | File | 61.77 KB | 0644 |
|
| colornames.py | File | 39.22 KB | 0644 |
|
| debug.py | File | 3.95 KB | 0644 |
|
| debugging_tools_manager.py | File | 10.69 KB | 0644 |
|
| event_manager.py | File | 36.07 KB | 0644 |
|
| flat_review.py | File | 48.89 KB | 0644 |
|
| flat_review_finder.py | File | 20.2 KB | 0644 |
|
| flat_review_presenter.py | File | 45.94 KB | 0644 |
|
| focus_manager.py | File | 11.52 KB | 0644 |
|
| generator.py | File | 67.07 KB | 0644 |
|
| guilabels.py | File | 56.38 KB | 0644 |
|
| highlighter.py | File | 6.95 KB | 0644 |
|
| input_event.py | File | 30.05 KB | 0644 |
|
| input_event_manager.py | File | 35.66 KB | 0644 |
|
| keybindings.py | File | 24.87 KB | 0644 |
|
| keynames.py | File | 9.55 KB | 0644 |
|
| label_inference.py | File | 19.77 KB | 0644 |
|
| learn_mode_presenter.py | File | 14.72 KB | 0644 |
|
| liveregions.py | File | 25.77 KB | 0644 |
|
| mathsymbols.py | File | 88.65 KB | 0644 |
|
| messages.py | File | 152.28 KB | 0644 |
|
| mouse_review.py | File | 23.34 KB | 0644 |
|
| notification_presenter.py | File | 14.17 KB | 0644 |
|
| object_navigator.py | File | 13.24 KB | 0644 |
|
| object_properties.py | File | 33.86 KB | 0644 |
|
| orca.py | File | 9.83 KB | 0644 |
|
| orca_gtkbuilder.py | File | 5.42 KB | 0644 |
|
| orca_gui_navlist.py | File | 6.51 KB | 0644 |
|
| orca_gui_prefs.py | File | 141.9 KB | 0644 |
|
| orca_gui_profile.py | File | 3.98 KB | 0644 |
|
| orca_i18n.py | File | 3.13 KB | 0644 |
|
| orca_modifier_manager.py | File | 13.76 KB | 0644 |
|
| orca_platform.py | File | 1.43 KB | 0644 |
|
| phonnames.py | File | 2.76 KB | 0644 |
|
| pronunciation_dict.py | File | 2.55 KB | 0644 |
|
| script.py | File | 11.11 KB | 0644 |
|
| script_manager.py | File | 14.68 KB | 0644 |
|
| script_utilities.py | File | 64.21 KB | 0644 |
|
| settings.py | File | 10.66 KB | 0644 |
|
| settings_manager.py | File | 27.13 KB | 0644 |
|
| sleep_mode_manager.py | File | 5.04 KB | 0644 |
|
| sound.py | File | 5.51 KB | 0644 |
|
| sound_generator.py | File | 48.88 KB | 0644 |
|
| speech.py | File | 8.87 KB | 0644 |
|
| speech_and_verbosity_manager.py | File | 27.71 KB | 0644 |
|
| speech_generator.py | File | 163.53 KB | 0644 |
|
| speechdispatcherfactory.py | File | 24.68 KB | 0644 |
|
| speechserver.py | File | 8 KB | 0644 |
|
| spellcheck.py | File | 18.11 KB | 0644 |
|
| spiel.py | File | 25.59 KB | 0644 |
|
| ssml.py | File | 6.71 KB | 0644 |
|
| structural_navigation.py | File | 77.63 KB | 0644 |
|
| system_information_presenter.py | File | 7.44 KB | 0644 |
|
| table_navigator.py | File | 29.78 KB | 0644 |
|
| text_attribute_names.py | File | 27.31 KB | 0644 |
|
| where_am_i_presenter.py | File | 21.59 KB | 0644 |
|