Repository: godotengine/godot
File: editor/doc/editor_help.cpp (C++)

Code before:
void EditorHelpBitTooltip::_target_gui_input(const Ref<InputEvent> &p_event) {
	// Only scrolling is not checked in `NOTIFICATION_INTERNAL_PROCESS`.
	const Ref<InputEventMouseButton> mb = p_event;
	if (mb.is_valid()) {
		switch (mb->get_button_index()) {
			case MouseButton::WHEEL_UP:
			case MouseButton::WHEEL_DOWN:
			case MouseButton::WHEEL_LEFT:
			case MouseButton::WHEEL_RIGHT:
				queue_free();
				break;
			default:
				break;
		}
	}

	const Ref<InputEventKey> k = p_event;
	if (k.is_valid() && k->is_pressed()) {
		queue_free();
	}
}

void EditorHelpBitTooltip::_shortcut_pressed(Control *p_target) {
	TextEdit *tx = Object::cast_to<TextEdit>(p_target);
	if (tx) {
		popup_under_position(tx->get_global_position() + tx->get_caret_draw_pos() + Point2(0, tx->get_line_height()));
	}
}

void EditorHelpBitTooltip::_notification(int p_what) {
	switch (p_what) {
		case NOTIFICATION_ENTER_TREE:
			_is_tooltip_visible = true;
			_enter_tree_time = OS::get_singleton()->get_ticks_msec();
			break;
		case NOTIFICATION_EXIT_TREE:
			_is_tooltip_visible = false;
			break;
		case NOTIFICATION_WM_MOUSE_ENTER:
			_is_mouse_inside_tooltip = true;
			timer->stop();
			break;
		case NOTIFICATION_WM_MOUSE_EXIT:
			_is_mouse_inside_tooltip = false;
			_start_timer();
			break;
		case NOTIFICATION_INTERNAL_PROCESS: {
			// A workaround to hide the tooltip since the window does not receive keyboard events
			// with `FLAG_POPUP` and `FLAG_NO_FOCUS` flags, so we can't use `_input_from_window()`.
			if (is_inside_tree()) {
				if (Input::get_singleton()->is_action_just_pressed(SNAME("ui_cancel"), true)) {

Review comment (suggestion):
This position is not correct if the TextEdit is in a floating window.

Also it may be better to pass the position in from the ScriptTextEditor, so the EditorHelpBitTooltip doesn't need to care about TextEdit.

Code after:
void EditorHelpBitTooltip::_target_gui_input(const Ref<InputEvent> &p_event) {
	// Only scrolling is not checked in `NOTIFICATION_INTERNAL_PROCESS`.
	const Ref<InputEventMouseButton> mb = p_event;
	if (mb.is_valid()) {
		switch (mb->get_button_index()) {
			case MouseButton::WHEEL_UP:
			case MouseButton::WHEEL_DOWN:
			case MouseButton::WHEEL_LEFT:
			case MouseButton::WHEEL_RIGHT:
				queue_free();
				break;
			default:
				break;
		}
	}

	const Ref<InputEventKey> k = p_event;
	if (k.is_valid() && k->is_pressed()) {
		queue_free();
	}
}

void EditorHelpBitTooltip::_shortcut_pressed(Control *p_target) {
	TextEdit *tx = Object::cast_to<TextEdit>(p_target);
	if (tx) {
		popup_under_position(
				tx->get_global_position() + tx->get_caret_draw_pos() +
				Point2(0, tx->get_line_height()) + tx->get_window()->get_position_with_decorations());
	}
}

void EditorHelpBitTooltip::_notification(int p_what) {
	switch (p_what) {
		case NOTIFICATION_ENTER_TREE:
			_is_tooltip_visible = true;
			_enter_tree_time = OS::get_singleton()->get_ticks_msec();
			break;
		case NOTIFICATION_EXIT_TREE:
			_is_tooltip_visible = false;
			break;
		case NOTIFICATION_WM_MOUSE_ENTER:
			_is_mouse_inside_tooltip = true;
			timer->stop();
			break;
		case NOTIFICATION_WM_MOUSE_EXIT:
			_is_mouse_inside_tooltip = false;
			_start_timer();
			break;
		case NOTIFICATION_INTERNAL_PROCESS: {
			// A workaround to hide the tooltip since the window does not receive keyboard events
			// with `FLAG_POPUP` and `FLAG_NO_FOCUS` flags, so we can't use `_input_from_window()`.