rework _handle_selection()

* do not use timer for selection, due to issue with Engine.time_scale == 0
  * deciding on redraw based on target cell change
  * deciding on send to system based on mouse button up event
  * remove _on_selection_held() timer callback function and SelectionMode enum
* on non-Linux system use clipbord when copy_on_selection is active
This commit is contained in:
Robert Paciorek 2024-07-06 21:51:37 +00:00
parent 64aa0ff49a
commit ca97b654ee
2 changed files with 34 additions and 46 deletions

View file

@ -90,7 +90,6 @@ void Terminal::_bind_methods()
ClassDB::bind_method(D_METHOD("get_cell_size"), &Terminal::get_cell_size);
ClassDB::bind_method(D_METHOD("_on_frame_post_draw"), &Terminal::_on_frame_post_draw);
ClassDB::bind_method(D_METHOD("_on_gui_input", "event"), &Terminal::_gui_input);
ClassDB::bind_method(D_METHOD("_on_selection_held"), &Terminal::_on_selection_held);
}
Terminal::Terminal()
@ -742,9 +741,11 @@ void Terminal::select(const int p_from_line, const int p_from_column, const int
String selection = copy_selection();
#if defined(__linux__)
if (copy_on_selection)
#if defined(__linux__)
DisplayServer::get_singleton()->clipboard_set_primary(selection);
#else
DisplayServer::get_singleton()->clipboard_set(selection);
#endif
if (selection.length() > 0) {
@ -784,11 +785,6 @@ int Terminal::get_inverse_mode() const {
void Terminal::initialize_input() {
selecting = false;
selection_mode = SelectionMode::NONE;
selection_timer = memnew(Timer);
selection_timer->set_wait_time(0.05);
selection_timer->connect("timeout", Callable(this, "_on_selection_held"));
add_child(selection_timer, false, INTERNAL_MODE_FRONT);
}
void Terminal::_handle_key_input(Ref<InputEventKey> event) {
@ -862,53 +858,48 @@ void Terminal::_handle_selection(Ref<InputEventMouse> event) {
Ref<InputEventMouseButton> mb = event;
if (mb.is_valid()) {
if (!mb->is_pressed() || mb->get_button_index() != MOUSE_BUTTON_LEFT)
if (!selecting || mb->get_button_index() != MOUSE_BUTTON_LEFT)
return;
if (!mb->is_pressed()) {
if (copy_on_selection) {
#if defined(__linux__)
DisplayServer::get_singleton()->clipboard_set_primary(copy_selection());
#else
DisplayServer::get_singleton()->clipboard_set(copy_selection());
#endif
}
} else {
if (selecting) {
selecting = false;
selection_mode = SelectionMode::NONE;
tsm_screen_selection_reset(screen);
queue_redraw();
}
selecting = false;
selection_mode = SelectionMode::POINTER;
}
return;
}
Ref<InputEventMouseMotion> mm = event;
if (mm.is_valid()) {
if ((mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) && selection_mode != SelectionMode::NONE && !selecting) {
if (mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
if (!selecting) {
selecting = true;
Vector2 start = event->get_position() / cell_size;
tsm_screen_selection_start(screen, start.x, start.y);
selection_last_point = event->get_position() / cell_size;
tsm_screen_selection_start(screen, selection_last_point.x, selection_last_point.y);
queue_redraw();
selection_timer->start();
}
return;
}
}
void Terminal::_on_selection_held() {
if (!(Input::get_singleton()->is_mouse_button_pressed(MOUSE_BUTTON_LEFT)) || selection_mode == SelectionMode::NONE) {
#if defined(__linux__)
if (copy_on_selection) {
DisplayServer::get_singleton()->clipboard_set_primary(copy_selection());
}
#endif
selection_timer->stop();
return;
}
Vector2 target = get_local_mouse_position() / cell_size;
} else {
Vector2i target = get_local_mouse_position() / cell_size;
if (selection_last_point != target) {
selection_last_point = target;
tsm_screen_selection_target(screen, target.x, target.y);
queue_redraw();
selection_timer->start();
}
}
}
}
}
// Add default theme items for the "Terminal" theme type if they don't exist.
// These defaults match Godot's built-in default theme (note: this is different from the default editor theme).
void Terminal::set_default_theme_items() {

View file

@ -184,12 +184,9 @@ namespace godot
void _handle_mouse_wheel(Ref<InputEventMouseButton> event);
enum SelectionMode { NONE, POINTER };
bool selecting = false;
SelectionMode selection_mode = SelectionMode::NONE;
Timer *selection_timer;
Vector2i selection_last_point;
void _handle_selection(Ref<InputEventMouse> event);
void _on_selection_held();
typedef std::function<int(struct tsm_screen*, char**)> ScreenCopyFunction;
String _copy_screen(ScreenCopyFunction func);