diff --git a/com.jeffser.Alpaca.json b/com.jeffser.Alpaca.json index 2c4d688..9d96e0e 100644 --- a/com.jeffser.Alpaca.json +++ b/com.jeffser.Alpaca.json @@ -167,6 +167,18 @@ } ] }, + { + "name": "vte", + "buildsystem": "meson", + "config-opts": ["-Dvapi=false"], + "sources": [ + { + "type": "archive", + "url": "https://gitlab.gnome.org/GNOME/vte/-/archive/0.78.0/vte-0.78.0.tar.gz", + "sha256": "82e19d11780fed4b66400f000829ce5ca113efbbfb7975815f26ed93e4c05f2d" + } + ] + }, { "name" : "alpaca", "builddir" : true, diff --git a/src/custom_widgets/terminal_widget.py b/src/custom_widgets/terminal_widget.py new file mode 100644 index 0000000..858b576 --- /dev/null +++ b/src/custom_widgets/terminal_widget.py @@ -0,0 +1,33 @@ +#chat_widget.py +""" +Handles the terminal widget +""" + +import gi +gi.require_version('Gtk', '4.0') +gi.require_version('Vte', '3.91') +from gi.repository import Gtk, Vte, GLib, Pango + +class terminal(Vte.Terminal): + __gtype_name__ = 'AlpacaTerminal' + + def __init__(self, script:list): + super().__init__(css_classes=["terminal"]) + self.set_font(Pango.FontDescription.from_string("Monospace 12")) + + pty = Vte.Pty.new_sync(Vte.PtyFlags.DEFAULT, None) + + self.set_pty(pty) + pty.spawn_async( + GLib.get_current_dir(), + script, + [], + GLib.SpawnFlags.DEFAULT, + None, + None, + -1, + None, + None + ) + + self.connect('child-exited', lambda *_: print('exited')) diff --git a/src/dialogs.py b/src/dialogs.py index ab1a85e..469df25 100644 --- a/src/dialogs.py +++ b/src/dialogs.py @@ -428,43 +428,11 @@ def run_script_response(self, dialog, task, script, language_name): with open(os.path.join(cache_dir, 'temp_python_script.py'), 'w') as f: f.write(script) script = 'python3 {}'.format(os.path.join(cache_dir, 'temp_python_script.py')) - script += '; read -p "\n(Alpaca) {}"'.format(_('Press Enter to close...')) - using_flatpak = shutil.which('flatpak-spawn') + script += '; echo "\n(Alpaca) {}"'.format(_('Script exited')) + if shutil.which('flatpak-spawn'): + script = 'echo "{}\n";'.format(_('The script is contained inside Flatpak')) + script - try: - terminal_to_use = None - if os.path.isfile(os.path.join(config_dir, 'FORCE_TERMINAL')): - with open(os.path.join(config_dir, 'FORCE_TERMINAL'), 'r') as f: - terminal_to_use = f.read().split('\n')[0].split(' ') - else: - terminals = [['kgx', '-e'], ['gnome-terminal', '--'], ['konsole', '-e'], ['xterm', '-e'], ['lxterminal', '-e'], ['kitty', '-e'], ['xfce4-terminal', '-x'], ['alacritty', '-e'], ['yakuake', '-e']] - for terminal in terminals: - result = subprocess.run( - ['flatpak-spawn', '--host', 'sh', '-c', f'command -v {terminal[0]}'] if using_flatpak else ['sh' '-c', f'command -v {terminal[0]}'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - if result.returncode == 0: - terminal_to_use = terminal - break - - if terminal_to_use: - if using_flatpak: - run_command = ['flatpak-spawn', '--host'] - run_command[2:2] = terminal_to_use - else: - run_command = terminal_to_use - if terminal_to_use[0] == 'flatpak': - run_command.append(f'bash -c {script}') - else: - run_command.append('bash') - run_command.append('-c') - run_command.append(script) - subprocess.Popen(run_command) - else: - self.show_toast(_('No compatible terminal was found in the system'), self.main_overlay) - except Exception as e: - logger.error(f'Error running script on {terminal_to_use}: {e}') + self.run_terminal(['bash', '-c', script]) def run_script(self, script:str, language_name:str): dialog = Adw.AlertDialog( diff --git a/src/meson.build b/src/meson.build index 1655fc4..5de47c2 100644 --- a/src/meson.build +++ b/src/meson.build @@ -50,7 +50,8 @@ custom_widgets = [ 'custom_widgets/table_widget.py', 'custom_widgets/message_widget.py', 'custom_widgets/chat_widget.py', - 'custom_widgets/model_widget.py' + 'custom_widgets/model_widget.py', + 'custom_widgets/terminal_widget.py' ] install_data(alpaca_sources, install_dir: moduledir) diff --git a/src/style.css b/src/style.css index 695dc27..007f224 100644 --- a/src/style.css +++ b/src/style.css @@ -36,4 +36,7 @@ stacksidebar { } .code_block { font-family: monospace; -} \ No newline at end of file +} +.terminal { + padding: 10px; +} diff --git a/src/window.py b/src/window.py index 64af061..75df5fe 100644 --- a/src/window.py +++ b/src/window.py @@ -32,7 +32,7 @@ gi.require_version('GdkPixbuf', '2.0') from gi.repository import Adw, Gtk, Gdk, GLib, GtkSource, Gio, GdkPixbuf from . import dialogs, connection_handler -from .custom_widgets import message_widget, chat_widget, model_widget +from .custom_widgets import message_widget, chat_widget, model_widget, terminal_widget from .internal import config_dir, data_dir, cache_dir, source_dir logger = logging.getLogger(__name__) @@ -118,6 +118,9 @@ class AlpacaWindow(Adw.ApplicationWindow): style_manager = Adw.StyleManager() + terminal_scroller = Gtk.Template.Child() + terminal_dialog = Gtk.Template.Child() + @Gtk.Template.Callback() def stop_message(self, button=None): self.chat_list_box.get_current_chat().stop_message() @@ -368,6 +371,10 @@ class AlpacaWindow(Adw.ApplicationWindow): clipboard.read_text_async(None, self.cb_text_received) clipboard.read_texture_async(None, self.cb_image_received) + def run_terminal(self, script:list): + self.terminal_scroller.set_child(terminal_widget.terminal(script)) + self.terminal_dialog.present(self) + def convert_model_name(self, name:str, mode:int) -> str: # mode=0 name:tag -> Name (tag) | mode=1 Name (tag) -> name:tag try: if mode == 0: diff --git a/src/window.ui b/src/window.ui index 853dac8..aba1012 100644 --- a/src/window.ui +++ b/src/window.ui @@ -475,6 +475,30 @@ + + + Manage models dialog + + Terminal + true + 400 + 600 + + + + + + + + + + + + + + Manage models dialog