Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code editor scrolls to show the caret when it's window loses focus #89285

Open
mieldepoche opened this issue Mar 8, 2024 · 4 comments
Open

Comments

@mieldepoche
Copy link
Contributor

Tested versions

  • occurs in v4.3.dev4.official [df78c06]
  • does not occur in v4.2.1.stable.official [b09f793]

System information

linux

Issue description

  • when
    1. the focus leaves the window the code editor is in (either the full editor or the code editor in its own window), and
    2. the code editor is focused
  • then the code editor scrolls to make the edition caret visible if it's outside the view
simplescreenrecorder-2024-03-08_16.41.44.mp4

Steps to reproduce

  1. get a long gdscript file
  2. put the caret in a line and scroll it outside of the screen
  3. give the focus to another os window
  4. the code editor should scroll on its own

Minimal reproduction project (MRP)

any

@kitbdev
Copy link
Contributor

kitbdev commented Mar 9, 2024

Cannot reproduce in Godot v4.3.dev4 on Windows 10.0.22621

@smnast
Copy link
Contributor

smnast commented Mar 13, 2024

I can consistently reproduce this error on my Linux system (void linux, i3wm) in Godot v4.3.dev4.

The relevant function here is TextEdit::adjust_viewport_to_caret, which scrolls the editor to show the caret.
Using a debugger, I found this function was always called from TextEdit::_notification: (I'll keep the code snippets to just the relevant code)

case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
	if (has_focus()) {
		adjust_viewport_to_caret(0); // <--- our problem
	}
} break;

The source of this IME update notification seems to be from DisplayServerX11::process_events

case FocusOut: {
	if (wd.ime_active) {
		OS_Unix::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
	}
} break;

Now this notification would imply that IME is active, which seems to always be the case because of TextEdit::_update_ime_window_position:

void TextEdit::_update_ime_window_position() {
	DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
}

And this update function is called in TextEdit::_notification, in the case of a draw notification:

case NOTIFICATION_DRAW: {
	// at the bottom of this absurdly long case...
	if (has_focus()) {
		_update_ime_window_position();
	}
} break;

So it seems that for the viewport to scroll to show the cursor, the flag for if IME is active must be set.
But this flag is always set as long as the window has focus and can draw.

Perhaps someone with more experience in Godot's IME interface can understand why this is the case.

@ConteZero
Copy link
Contributor

I can confirm the issue, Godot 4.3 with Opensuse Tumbleweed (KDE), it's really annoying.

@kitbdev
Copy link
Contributor

kitbdev commented Sep 18, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants