Add support for key input

This commit is contained in:
Leroy Hopson 2024-02-15 06:53:53 +13:00
parent 580760ffad
commit 3fcaa79f6e
No known key found for this signature in database
GPG key ID: D2747312A6DB51AA
2 changed files with 59 additions and 1 deletions

View file

@ -6,11 +6,13 @@
#include <godot_cpp/classes/control.hpp> #include <godot_cpp/classes/control.hpp>
#include <godot_cpp/classes/font.hpp> #include <godot_cpp/classes/font.hpp>
#include <godot_cpp/classes/image_texture.hpp> #include <godot_cpp/classes/image_texture.hpp>
#include <godot_cpp/classes/input_event_key.hpp>
#include <godot_cpp/classes/rendering_server.hpp> #include <godot_cpp/classes/rendering_server.hpp>
#include <godot_cpp/classes/resource_loader.hpp> #include <godot_cpp/classes/resource_loader.hpp>
#include <godot_cpp/classes/shader_material.hpp> #include <godot_cpp/classes/shader_material.hpp>
#include <godot_cpp/classes/timer.hpp> #include <godot_cpp/classes/timer.hpp>
#include <libtsm.h> #include <libtsm.h>
#include <xkbcommon/xkbcommon-keysyms.h>
#define SHADERS_DIR "res://addons/godot_xterm/shaders/" #define SHADERS_DIR "res://addons/godot_xterm/shaders/"
#define FOREGROUND_SHADER_PATH SHADERS_DIR "foreground.gdshader" #define FOREGROUND_SHADER_PATH SHADERS_DIR "foreground.gdshader"
@ -64,10 +66,13 @@ void Terminal::_bind_methods()
ClassDB::bind_method(D_METHOD("write", "data"), &Terminal::write); ClassDB::bind_method(D_METHOD("write", "data"), &Terminal::write);
ClassDB::bind_method(D_METHOD("get_cursor_pos"), &Terminal::get_cursor_pos); ClassDB::bind_method(D_METHOD("get_cursor_pos"), &Terminal::get_cursor_pos);
ClassDB::bind_method(D_METHOD("_on_gui_input", "event"), &Terminal::_gui_input);
} }
Terminal::Terminal() Terminal::Terminal()
{ {
set_focus_mode(FOCUS_ALL);
max_scrollback = 1000; max_scrollback = 1000;
blink_on_time = 0.6; blink_on_time = 0.6;
@ -93,6 +98,7 @@ Terminal::Terminal()
} }
tsm_vte_set_bell_cb(vte, &Terminal::_bell_cb, this); tsm_vte_set_bell_cb(vte, &Terminal::_bell_cb, this);
initialize_input();
initialize_rendering(); initialize_rendering();
update_theme(); update_theme();
update_sizes(); update_sizes();
@ -163,6 +169,10 @@ String Terminal::write(const Variant data)
return response.get_string_from_utf8(); return response.get_string_from_utf8();
} }
void Terminal::_gui_input(const Ref<InputEvent> &event) {
_handle_key_input(event);
}
void Terminal::_notification(int what) void Terminal::_notification(int what)
{ {
switch (what) switch (what)
@ -593,3 +603,45 @@ void Terminal::set_inverse_mode(const int mode) {
int Terminal::get_inverse_mode() const { int Terminal::get_inverse_mode() const {
return static_cast<int>(inverse_mode); return static_cast<int>(inverse_mode);
} }
void Terminal::initialize_input() {
connect("gui_input", Callable(this, "_on_gui_input"));
}
void Terminal::_handle_key_input(Ref<InputEventKey> event) {
if (!event.is_valid() || !event->is_pressed())
return;
const Key keycode = event->get_keycode();
char32_t unicode = event->get_unicode();
uint32_t ascii = unicode <= 127 ? unicode : 0;
unsigned int mods = 0;
if (event->is_alt_pressed())
mods |= TSM_SHIFT_MASK;
if (event->is_ctrl_pressed())
mods |= TSM_CONTROL_MASK;
if (event->is_shift_pressed())
mods |= TSM_SHIFT_MASK;
std::pair<Key, char32_t> key = {keycode, unicode};
uint32_t keysym = (KEY_MAP.count(key) > 0) ? KEY_MAP.at(key) : XKB_KEY_NoSymbol;
last_input_event_key = event;
tsm_vte_handle_keyboard(vte, keysym, ascii, mods, unicode ? unicode : TSM_VTE_INVALID);
// Return to the bottom of the scrollback buffer if we scrolled up. Ignore
// modifier keys pressed in isolation or if Ctrl+Shift modifier keys are
// pressed.
std::set<Key> mod_keys = {KEY_ALT, KEY_SHIFT, KEY_CTRL, KEY_META};
if (mod_keys.find(keycode) == mod_keys.end() &&
!(event->is_ctrl_pressed() && event->is_shift_pressed())) {
tsm_screen_sb_reset(screen);
queue_redraw();
}
// Prevent focus changing to other inputs when pressing Tab or Arrow keys.
std::set<Key> tab_arrow_keys = {KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN, KEY_TAB};
if (tab_arrow_keys.find(keycode) != tab_arrow_keys.end())
accept_event();
}

View file

@ -7,6 +7,7 @@
#include <godot_cpp/classes/control.hpp> #include <godot_cpp/classes/control.hpp>
#include <godot_cpp/classes/image_texture.hpp> #include <godot_cpp/classes/image_texture.hpp>
#include <godot_cpp/classes/input_event_key.hpp>
#include <godot_cpp/classes/rendering_server.hpp> #include <godot_cpp/classes/rendering_server.hpp>
#include <godot_cpp/classes/shader_material.hpp> #include <godot_cpp/classes/shader_material.hpp>
#include <godot_cpp/classes/timer.hpp> #include <godot_cpp/classes/timer.hpp>
@ -75,6 +76,7 @@ namespace godot
String write(const Variant data); String write(const Variant data);
void _gui_input(const Ref<InputEvent> &event) override;
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -146,6 +148,10 @@ namespace godot
void _get_property_list(List<PropertyInfo> *p_list) const; void _get_property_list(List<PropertyInfo> *p_list) const;
bool _is_valid_color_name(const String &p_name); bool _is_valid_color_name(const String &p_name);
bool _is_valid_font_type(const String &p_name); bool _is_valid_font_type(const String &p_name);
Ref<InputEventKey> last_input_event_key;
void initialize_input();
void _handle_key_input(Ref<InputEventKey> event);
}; };
} // namespace godot } // namespace godot