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("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_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_gui_input", "event"), &Terminal::_gui_input);
ClassDB::bind_method(D_METHOD("_on_selection_held"), &Terminal::_on_selection_held);
} }
Terminal::Terminal() 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(); String selection = copy_selection();
#if defined(__linux__)
if (copy_on_selection) if (copy_on_selection)
#if defined(__linux__)
DisplayServer::get_singleton()->clipboard_set_primary(selection); DisplayServer::get_singleton()->clipboard_set_primary(selection);
#else
DisplayServer::get_singleton()->clipboard_set(selection);
#endif #endif
if (selection.length() > 0) { if (selection.length() > 0) {
@ -784,11 +785,6 @@ int Terminal::get_inverse_mode() const {
void Terminal::initialize_input() { void Terminal::initialize_input() {
selecting = false; 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) { void Terminal::_handle_key_input(Ref<InputEventKey> event) {
@ -862,52 +858,47 @@ void Terminal::_handle_selection(Ref<InputEventMouse> event) {
Ref<InputEventMouseButton> mb = event; Ref<InputEventMouseButton> mb = event;
if (mb.is_valid()) { 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; 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) { if (selecting) {
selecting = false; selecting = false;
selection_mode = SelectionMode::NONE;
tsm_screen_selection_reset(screen); tsm_screen_selection_reset(screen);
queue_redraw(); queue_redraw();
} }
}
selecting = false;
selection_mode = SelectionMode::POINTER;
return; return;
} }
Ref<InputEventMouseMotion> mm = event; Ref<InputEventMouseMotion> mm = event;
if (mm.is_valid()) { 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; selecting = true;
Vector2 start = event->get_position() / cell_size; selection_last_point = event->get_position() / cell_size;
tsm_screen_selection_start(screen, start.x, start.y); tsm_screen_selection_start(screen, selection_last_point.x, selection_last_point.y);
queue_redraw(); queue_redraw();
selection_timer->start(); } else {
} Vector2i target = get_local_mouse_position() / cell_size;
return; if (selection_last_point != target) {
} selection_last_point = target;
}
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;
tsm_screen_selection_target(screen, target.x, target.y); tsm_screen_selection_target(screen, target.x, target.y);
queue_redraw(); queue_redraw();
selection_timer->start();
} }
}
}
}
}
// Add default theme items for the "Terminal" theme type if they don't exist. // 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). // These defaults match Godot's built-in default theme (note: this is different from the default editor theme).

View file

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