mirror of
https://github.com/lihop/godot-xterm.git
synced 2024-11-12 21:50:26 +01:00
feat(pty): add terminal_path property to pty
Property can be set to the NodePath of a Terminal node. Doing so will conveniently set up the neccessary signals between Terminal and PTY for them to function together.
This commit is contained in:
parent
fa49834347
commit
e816396d60
3 changed files with 73 additions and 8 deletions
|
@ -67,6 +67,10 @@ void PTY::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("is_using_threads"), &PTY::is_using_threads);
|
ClassDB::bind_method(D_METHOD("is_using_threads"), &PTY::is_using_threads);
|
||||||
ClassDB::add_property("PTY", PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads");
|
ClassDB::add_property("PTY", PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_terminal_path", "path"), &PTY::set_terminal_path);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_terminal_path"), &PTY::get_terminal_path);
|
||||||
|
ClassDB::add_property("PTY", PropertyInfo(Variant::NODE_PATH, "terminal_path", PropertyHint::PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Terminal"), "set_terminal_path", "get_terminal_path");
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_pts_name"), &PTY::get_pts_name);
|
ClassDB::bind_method(D_METHOD("get_pts_name"), &PTY::get_pts_name);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("fork", "file", "args", "cwd", "cols", "rows"), &PTY::fork, DEFVAL(""), DEFVAL(PackedStringArray()), DEFVAL("."), DEFVAL(80), DEFVAL(24));
|
ClassDB::bind_method(D_METHOD("fork", "file", "args", "cwd", "cols", "rows"), &PTY::fork, DEFVAL(""), DEFVAL(PackedStringArray()), DEFVAL("."), DEFVAL(80), DEFVAL(24));
|
||||||
|
@ -145,6 +149,36 @@ bool PTY::is_using_threads() const {
|
||||||
return use_threads;
|
return use_threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PTY::set_terminal_path(NodePath p_terminal_path) {
|
||||||
|
terminal_path = p_terminal_path;
|
||||||
|
|
||||||
|
Callable write = Callable(this, "write");
|
||||||
|
Callable resizev = Callable(this, "resizev");
|
||||||
|
|
||||||
|
// Disconnect the current terminal, if any.
|
||||||
|
if (terminal != nullptr) {
|
||||||
|
disconnect("data_received", Callable(terminal, "write"));
|
||||||
|
terminal->disconnect("data_sent", write);
|
||||||
|
terminal->disconnect("size_changed", resizev);
|
||||||
|
}
|
||||||
|
|
||||||
|
terminal = Object::cast_to<Terminal>(get_node_or_null(terminal_path));
|
||||||
|
if (terminal == nullptr) return;
|
||||||
|
|
||||||
|
// Connect the new terminal.
|
||||||
|
resize(terminal->get_cols(), terminal->get_rows());
|
||||||
|
if (!terminal->is_connected("size_changed", resizev))
|
||||||
|
terminal->connect("size_changed", resizev, CONNECT_PERSIST);
|
||||||
|
if (!terminal->is_connected("data_sent", write))
|
||||||
|
terminal->connect("data_sent", write, CONNECT_PERSIST);
|
||||||
|
if (!is_connected("data_received", Callable(terminal, "write")))
|
||||||
|
connect("data_received", Callable(terminal, "write"), CONNECT_PERSIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodePath PTY::get_terminal_path() const {
|
||||||
|
return terminal_path;
|
||||||
|
}
|
||||||
|
|
||||||
String PTY::get_pts_name() const {
|
String PTY::get_pts_name() const {
|
||||||
return pts_name;
|
return pts_name;
|
||||||
}
|
}
|
||||||
|
@ -213,8 +247,6 @@ void PTY::resize(const int p_cols, const int p_rows) {
|
||||||
#if defined(__linux__) || defined(__APPLE__)
|
#if defined(__linux__) || defined(__APPLE__)
|
||||||
if (fd > -1) {
|
if (fd > -1) {
|
||||||
PTYUnix::resize(fd, cols, rows);
|
PTYUnix::resize(fd, cols, rows);
|
||||||
} else {
|
|
||||||
ERR_PRINT("fd <= -1");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -303,9 +335,11 @@ void PTY::_close() {
|
||||||
if (!uv_is_closing((uv_handle_t *)&async_handle)) {
|
if (!uv_is_closing((uv_handle_t *)&async_handle)) {
|
||||||
uv_close((uv_handle_t *)&async_handle, _close_cb);
|
uv_close((uv_handle_t *)&async_handle, _close_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_run(&loop, UV_RUN_NOWAIT);
|
if (status == STATUS_OPEN) {
|
||||||
uv_loop_close(&loop);
|
uv_run(&loop, UV_RUN_NOWAIT);
|
||||||
|
uv_loop_close(&loop);
|
||||||
|
}
|
||||||
|
|
||||||
if (fd > 0) close(fd);
|
if (fd > 0) close(fd);
|
||||||
if (pid > 0) kill(SIGNAL_SIGHUP);
|
if (pid > 0) kill(SIGNAL_SIGHUP);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "terminal.h"
|
||||||
|
|
||||||
#include <godot_cpp/classes/mutex.hpp>
|
#include <godot_cpp/classes/mutex.hpp>
|
||||||
#include <godot_cpp/classes/node.hpp>
|
#include <godot_cpp/classes/node.hpp>
|
||||||
#include <godot_cpp/classes/os.hpp>
|
#include <godot_cpp/classes/os.hpp>
|
||||||
|
@ -57,6 +59,9 @@ namespace godot
|
||||||
void set_use_threads(bool p_use);
|
void set_use_threads(bool p_use);
|
||||||
bool is_using_threads() const;
|
bool is_using_threads() const;
|
||||||
|
|
||||||
|
void set_terminal_path(NodePath p_terminal_path);
|
||||||
|
NodePath get_terminal_path() const;
|
||||||
|
|
||||||
String get_pts_name() const;
|
String get_pts_name() const;
|
||||||
|
|
||||||
Error fork(const String &file = "", const PackedStringArray &args = PackedStringArray(), const String &cwd = ".", const int cols = 80, const int rows = 24);
|
Error fork(const String &file = "", const PackedStringArray &args = PackedStringArray(), const String &cwd = ".", const int cols = 80, const int rows = 24);
|
||||||
|
@ -83,6 +88,9 @@ namespace godot
|
||||||
|
|
||||||
String pts_name = "";
|
String pts_name = "";
|
||||||
|
|
||||||
|
NodePath terminal_path;
|
||||||
|
Terminal *terminal = nullptr;
|
||||||
|
|
||||||
String _get_fork_file(const String &file) const;
|
String _get_fork_file(const String &file) const;
|
||||||
Dictionary _get_fork_env() const;
|
Dictionary _get_fork_env() const;
|
||||||
PackedStringArray _parse_env(const Dictionary &env) const;
|
PackedStringArray _parse_env(const Dictionary &env) const;
|
||||||
|
|
|
@ -24,9 +24,8 @@ class TestInterface:
|
||||||
func test_has_property_rows() -> void:
|
func test_has_property_rows() -> void:
|
||||||
assert_has_property_with_default_value("rows", 24)
|
assert_has_property_with_default_value("rows", 24)
|
||||||
|
|
||||||
# TODO: Implement terminal_path property.
|
func test_has_property_terminal_path() -> void:
|
||||||
func xtest_has_property_terminal_path() -> void:
|
assert_has_property_with_default_value("terminal_path", NodePath())
|
||||||
assert_has_property("terminal_path")
|
|
||||||
|
|
||||||
func test_has_proprty_use_os_env() -> void:
|
func test_has_proprty_use_os_env() -> void:
|
||||||
assert_has_property_with_default_value("use_os_env", true)
|
assert_has_property_with_default_value("use_os_env", true)
|
||||||
|
@ -82,3 +81,27 @@ class TestInterface:
|
||||||
|
|
||||||
func test_has_no_visible_children():
|
func test_has_no_visible_children():
|
||||||
assert_eq(subject.get_child_count(), 0)
|
assert_eq(subject.get_child_count(), 0)
|
||||||
|
|
||||||
|
|
||||||
|
class TestSetTerminalPath:
|
||||||
|
extends PTYTest
|
||||||
|
|
||||||
|
var terminal: Terminal
|
||||||
|
|
||||||
|
func before_each():
|
||||||
|
super.before_each()
|
||||||
|
terminal = Terminal.new()
|
||||||
|
add_child_autofree(terminal)
|
||||||
|
subject.terminal_path = terminal.get_path()
|
||||||
|
|
||||||
|
func test_terminal_path_is_set():
|
||||||
|
assert_eq(subject.terminal_path, terminal.get_path())
|
||||||
|
|
||||||
|
func test_data_sent_is_connected():
|
||||||
|
assert_connected(terminal, subject, "data_sent", "write")
|
||||||
|
|
||||||
|
func test_size_changed_is_connected():
|
||||||
|
assert_connected(terminal, subject, "size_changed", "resizev")
|
||||||
|
|
||||||
|
func test_data_received_is_connected():
|
||||||
|
assert_connected(subject, terminal, "data_received", "write")
|
||||||
|
|
Loading…
Reference in a new issue