diff --git a/src/__builtins__.py b/src/__builtins__.py index 37abfc6..5bfe5a6 100644 --- a/src/__builtins__.py +++ b/src/__builtins__.py @@ -46,9 +46,11 @@ builtins.settings_manager = SettingsManager() settings_manager.load_settings() builtins.settings = settings_manager.settings -builtins.logger = Logger(settings_manager.get_home_config_path(), \ - _ch_log_lvl=settings.debugging.ch_log_lvl, \ - _fh_log_lvl=settings.debugging.fh_log_lvl).get_logger() +builtins.logger = Logger( + settings_manager.get_home_config_path(), \ + _ch_log_lvl = settings.debugging.ch_log_lvl, \ + _fh_log_lvl = settings.debugging.fh_log_lvl + ).get_logger() builtins.threaded = threaded_wrapper builtins.daemon_threaded = daemon_threaded_wrapper @@ -60,6 +62,6 @@ def custom_except_hook(exc_type, exc_value, exc_traceback): sys.__excepthook__(exc_type, exc_value, exc_traceback) return - logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)) + logger.error("Uncaught exception", exc_info = (exc_type, exc_value, exc_traceback)) sys.excepthook = custom_except_hook \ No newline at end of file diff --git a/src/app.py b/src/app.py index 2f39b3b..1570122 100644 --- a/src/app.py +++ b/src/app.py @@ -30,11 +30,11 @@ class Application: def load_ipc(self): - args, unknownargs = settings_manager.get_starting_args() - ipc_server = IPCServer() + args, \ + unknownargs = settings_manager.get_starting_args() + ipc_server = IPCServer() self.ipc_realization_check(ipc_server) - if not ipc_server.is_ipc_alive: for arg in unknownargs + [args.new_tab,]: if os.path.isfile(arg): diff --git a/src/core/containers/right_container.py b/src/core/containers/right_container.py index 5b61e21..a8c0138 100644 --- a/src/core/containers/right_container.py +++ b/src/core/containers/right_container.py @@ -6,6 +6,7 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk # Application imports +from ..widgets.vte_widget import VteWidget @@ -33,4 +34,5 @@ class RightContainer(Gtk.Box): ... def _load_widgets(self): - ... \ No newline at end of file + vte_widget = VteWidget() + self.add( vte_widget ) \ No newline at end of file diff --git a/src/core/controllers/base_controller.py b/src/core/controllers/base_controller.py index db9d05a..221a76a 100644 --- a/src/core/controllers/base_controller.py +++ b/src/core/controllers/base_controller.py @@ -18,9 +18,8 @@ from .bridge_controller import BridgeController class BaseController(IPCSignalsMixin, KeyboardSignalsMixin, BaseControllerData): def __init__(self): - self.collect_files_dirs() - self.setup_controller_data() + self._setup_controller_data() self._setup_styling() self._setup_signals() self._subscribe_to_events() diff --git a/src/core/controllers/base_controller_data.py b/src/core/controllers/base_controller_data.py index de531b4..f070ac5 100644 --- a/src/core/controllers/base_controller_data.py +++ b/src/core/controllers/base_controller_data.py @@ -14,7 +14,7 @@ from ..builder_wrapper import BuilderWrapper class BaseControllerData: ''' BaseControllerData contains most of the state of the app at ay given time. It also has some support methods. ''' - def setup_controller_data(self) -> None: + def _setup_controller_data(self) -> None: self.window = settings_manager.get_main_window() self.builder = BuilderWrapper() self.plugins_controller = PluginsController() @@ -25,10 +25,11 @@ class BaseControllerData: self.shift_down = False self.alt_down = False + self._collect_files_dirs() self._load_glade_file() - def collect_files_dirs(self): + def _collect_files_dirs(self): args, \ unknownargs = settings_manager.get_starting_args() files = [] diff --git a/src/core/widgets/vte_widget.py b/src/core/widgets/vte_widget.py new file mode 100644 index 0000000..608e84a --- /dev/null +++ b/src/core/widgets/vte_widget.py @@ -0,0 +1,125 @@ +# Python imports +import os + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +gi.require_version('Vte', '2.91') +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GLib +from gi.repository import Vte + +# Application imports +from libs.dto.event import Event + + + +class VteWidgetException(Exception): + ... + + + +class VteWidget(Vte.Terminal): + """ + https://stackoverflow.com/questions/60454326/how-to-implement-a-linux-terminal-in-a-pygtk-app-like-vscode-and-pycharm-has + """ + + def __init__(self): + super(VteWidget, self).__init__() + + self.cd_cmd_prefix = ("cd".encode(), "cd ".encode()) + self.dont_process = False + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + self._do_session_spawn() + + self.show() + + + def _setup_styling(self): + ctx = self.get_style_context() + ctx.add_class("vte-widget") + + self.set_clear_background(False) + self.set_enable_sixel(True) + self.set_cursor_shape( Vte.CursorShape.IBEAM ) + + def _setup_signals(self): + self.connect("commit", self._commit) + + def _subscribe_to_events(self): + event_system.subscribe("update_term_path", self.update_term_path) + + def _load_widgets(self): + ... + + def _do_session_spawn(self): + self.spawn_sync( + Vte.PtyFlags.DEFAULT, + settings_manager.get_home_path(), + ["/bin/bash"], + [], + GLib.SpawnFlags.DEFAULT, + None, None, + ) + + # Note: '-->:' is used as a delimiter to split on to get command actual. + # !!! DO NOT REMOVE UNLESS CODE UPDATED ACCORDINGLY !!! + startup_cmds = [ + "env -i /bin/bash --noprofile --norc\n", + "export TERM='xterm-256color'\n", + "export LC_ALL=C\n", + "export XDG_RUNTIME_DIR='/run/user/1000'\n", + "export DISPLAY=:0\n", + f"export XAUTHORITY='{settings_manager.get_home_path()}/.Xauthority'\n", + f"\nexport HOME='{settings_manager.get_home_path()}'\n", + "export PS1='\\h@\\u \\W -->: '\n", + "clear\n" + ] + + for i in startup_cmds: + self.run_command(i) + + def _commit(self, terminal, text, size): + if self.dont_process: + self.dont_process = False + return + + if not text.encode() == "\r".encode(): return + + text, attributes = self.get_text() + lines = text.strip().splitlines() + command_ran = None + + try: + command_ran = lines[-1].split("-->:")[1].strip() + except VteWidgetException as e: + logger.debud(e) + return + + if not command_ran[0:3].encode() in self.cd_cmd_prefix: + return + + target_path = command_ran.split( command_ran[0:3] )[1] + if target_path in (".", "./"): return + + if not target_path: + target_path = settings_manager.get_home_path() + + event = Event("pty_path_updated", "", target_path) + event_system.emit("handle_bridge_event", (event,)) + + def update_term_path(self, fpath): + self.dont_process = True + + cmds = [f"cd '{fpath}'\n", "clear\n"] + for i in cmds: + self.run_command(i) + + def run_command(self, cmd): + self.feed_child_binary(bytes(cmd, 'utf8')) \ No newline at end of file diff --git a/user_config/usr/share/app_name/context_path/resources/css/overrides.css b/user_config/usr/share/app_name/context_path/resources/css/overrides.css index 8501c90..950c496 100644 --- a/user_config/usr/share/app_name/context_path/resources/css/overrides.css +++ b/user_config/usr/share/app_name/context_path/resources/css/overrides.css @@ -1,6 +1,7 @@ html, body { display: block; - background-color: #32383e00; +// background-color: #32383e00; + background-color: rgba(39, 43, 52, 0.64); color: #ffffff; text-wrap: wrap; }