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

Mouse-driven focus does not behave as expected. #4237

Closed
xavierog opened this issue Feb 28, 2024 · 2 comments · Fixed by #4236
Closed

Mouse-driven focus does not behave as expected. #4237

xavierog opened this issue Feb 28, 2024 · 2 comments · Fixed by #4236

Comments

@xavierog
Copy link
Contributor

Context

I have decided to polish/refine everything related to focus within my project. Keyboard-driven focus (tab / Shift+tab) works fine but mouse-driven focus does not seem to match my expectations (my reference being full-fledged GUI applications: Windows/MacOS/X11/GTK/Qt).

Note: this issue was first discussed on Discord on 2024-02-28.

Expectations

In GUI applications, a common thing is: when you click text (be it selectable or not) or a seemingly "empty" area, your click gives focus to the focusable widget this text/area belongs to (either directly or indirectly).

Another way to put it (© @davep ): clicking on a non-focusable widget should focus the nearest (in terms of distance up the DOM) focusable ancestor.

Initial discussions on Discord tend to show these expectations make sense.

Current behaviour

These MREs reflect that, out of the box, the expected behaviour does not happen in a Textual application.

MRE #1
#!/usr/bin/env python3
from textual.app import App, ComposeResult
from textual.widgets import Input, Label, Static

class MyBoringWidget(Static, can_focus=True, can_focus_children=True):
	DEFAULT_CSS = """
		MyBoringWidget {
			background: $primary;
			padding: 2;
			margin: 1;
			border: tall yellow;
		}
	"""
	def compose(self) -> ComposeResult:
		label_text = '[bold reverse]clicking these characters does not grant focus[/]'
		yield Label(label_text)
		yield Input()
		yield Static(label_text)

class FocusMRE(App):
	DEFAULT_CSS = """
	*:focus {
		border: tall red !important;
	}
	"""
	def compose(self) -> ComposeResult:
		yield MyBoringWidget()
		yield MyBoringWidget()
		yield MyBoringWidget()

if __name__ == "__main__":
	app = FocusMRE()
	app.run()
MRE #2 (same as #1 with an extra Collapsible widget)
#!/usr/bin/env python3
from textual.app import App, ComposeResult
from textual.widgets import Input, Label, Static, Collapsible

class MyBoringWidget(Static, can_focus=True, can_focus_children=True):
	DEFAULT_CSS = """
		MyBoringWidget {
			background: $primary;
			padding: 2;
			margin: 1;
			border: tall yellow;
		}
	"""
	def compose(self) -> ComposeResult:
		label_text = '[bold reverse]clicking these characters does not grant focus[/]'
		with Collapsible(title='clicking the Collapsible.Contents does not grant focus either', collapsed=False):
			yield Label(label_text)
			yield Input()
			yield Static(label_text)

class FocusMRE(App):
	DEFAULT_CSS = """
	*:focus {
		border: tall red !important;
	}
	"""
	def compose(self) -> ComposeResult:
		yield MyBoringWidget()
		yield MyBoringWidget()
		yield MyBoringWidget()

if __name__ == "__main__":
	app = FocusMRE()
	app.run()

textual-focus-mre

Initial discussions on Discord tend to confirm there is some discrepancy between current and expected behaviour.

Textual Diagnostics

Versions

Name Value
Textual 0.52.1
Rich 13.7.0

Python

Name Value
Version 3.11.8
Implementation CPython
Compiler GCC 13.2.0
Executable ~/whatever/venv/bin/python3

Operating System

Name Value
System Linux
Release 6.6.15-amd64
Version #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04)

Terminal

Name Value
Terminal Application tmux (3.4)
TERM xterm-256color
COLORTERM truecolor
FORCE_COLOR Not set
NO_COLOR Not set

Rich Console options

Name Value
size width=232, height=54
legacy_windows False
min_width 1
max_width 232
is_terminal False
encoding utf-8
max_height 54
justify None
overflow None
no_wrap False
highlight None
markup None
height None
Copy link

We found the following entry in the FAQ which you may find helpful:

Feel free to close this issue if you found an answer in the FAQ. Otherwise, please give us a little time to review.

This is an automated reply, generated by FAQtory

@davep davep linked a pull request Feb 28, 2024 that will close this issue
Copy link

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

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

Successfully merging a pull request may close this issue.

1 participant