Skip to content

Commit 709b9ff

Browse files
committed
Revert "revert textinput changes"
This reverts commit 1e03f9a.
1 parent 2a6cb9e commit 709b9ff

File tree

2 files changed

+71
-28
lines changed

2 files changed

+71
-28
lines changed

gtk/src/toga_gtk/widgets/textinput.py

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,43 @@
11
from travertino.size import at_least
22

3+
from toga.handlers import WeakrefCallable
34
from toga.keys import Key
45
from toga_gtk.keys import toga_key
56

6-
from ..libs import Gtk, gtk_text_align
7+
from ..libs import GTK_VERSION, Gtk, gtk_text_align
78
from .base import Widget
89

910

1011
class TextInput(Widget):
1112
def create(self):
1213
self.native = Gtk.Entry()
1314

14-
self.native.connect("changed", self.gtk_on_change)
15-
self.native.connect("focus-in-event", self.gtk_focus_in_event)
16-
self.native.connect("focus-out-event", self.gtk_focus_out_event)
17-
self.native.connect("key-press-event", self.gtk_key_press_event)
15+
if GTK_VERSION < (4, 0, 0): # pragma: no-cover-if-gtk4
16+
self.native.connect("changed", self.gtk_on_change)
17+
self.native.connect("focus-in-event", self.gtk_focus_in_event)
18+
self.native.connect("focus-out-event", self.gtk_focus_out_event)
19+
self.native.connect("key-press-event", self.gtk_key_press_event)
20+
else: # pragma: no-cover-if-gtk3
21+
# Ideally we would connect to the `changed` signal, but it is
22+
# emitting two events each time text is changed
23+
# https://gitlab.gnome.org/GNOME/gtk/-/issues/7077
24+
self.native.connect("notify::text", self.gtk_on_change)
25+
26+
self.focus_controller = Gtk.EventControllerFocus.new()
27+
self.native.add_controller(self.focus_controller)
28+
29+
self.focus_controller.connect(
30+
"enter", WeakrefCallable(self.gtk_focus_in_event)
31+
)
32+
self.focus_controller.connect(
33+
"leave", WeakrefCallable(self.gtk_focus_out_event)
34+
)
35+
36+
self.key_controller = Gtk.EventControllerKey.new()
37+
self.native.add_controller(self.key_controller)
38+
self.key_controller.connect(
39+
"key-pressed", WeakrefCallable(self.gtk_key_pressed)
40+
)
1841

1942
def gtk_on_change(self, *_args):
2043
self.interface._value_changed()
@@ -25,10 +48,19 @@ def gtk_focus_in_event(self, *_args):
2548
def gtk_focus_out_event(self, *_args):
2649
self.interface.on_lose_focus()
2750

28-
def gtk_key_press_event(self, _entry, event):
29-
key_pressed = toga_key(event.keyval, event.state)
30-
if key_pressed and key_pressed["key"] in {Key.ENTER, Key.NUMPAD_ENTER}:
31-
self.interface.on_confirm()
51+
if GTK_VERSION < (4, 0, 0): # pragma: no-cover-if-gtk4
52+
53+
def gtk_key_press_event(self, _entry, event):
54+
key_pressed = toga_key(event.keyval, event.state)
55+
if key_pressed and key_pressed["key"] in {Key.ENTER, Key.NUMPAD_ENTER}:
56+
self.interface.on_confirm()
57+
58+
else: # pragma: no-cover-if-gtk3
59+
60+
def gtk_key_pressed(self, _controller, keyval, _keycode, state):
61+
key_pressed = toga_key(keyval, state)
62+
if key_pressed and key_pressed["key"] in {Key.ENTER, Key.NUMPAD_ENTER}:
63+
self.interface.on_confirm()
3264

3365
def get_readonly(self):
3466
return not self.native.get_property("editable")
@@ -55,21 +87,35 @@ def set_value(self, value):
5587
self.native.set_text(value)
5688

5789
def rehint(self):
58-
# print(
59-
# "REHINT",
60-
# self,
61-
# self._impl.get_preferred_width(),
62-
# self._impl.get_preferred_height(),
63-
# getattr(self, "_fixed_height", False),
64-
# getattr(self, "_fixed_width", False),
65-
# )
66-
width = self.native.get_preferred_width()
67-
height = self.native.get_preferred_height()
68-
69-
self.interface.intrinsic.width = at_least(
70-
max(self.interface._MIN_WIDTH, width[1])
71-
)
72-
self.interface.intrinsic.height = height[1]
90+
if GTK_VERSION < (4, 0, 0): # pragma: no-cover-if-gtk4
91+
# print(
92+
# "REHINT",
93+
# self,
94+
# self._impl.get_preferred_width(),
95+
# self._impl.get_preferred_height(),
96+
# getattr(self, "_fixed_height", False),
97+
# getattr(self, "_fixed_width", False),
98+
# )
99+
width = self.native.get_preferred_width()
100+
height = self.native.get_preferred_height()
101+
102+
self.interface.intrinsic.width = at_least(
103+
max(self.interface._MIN_WIDTH, width[1])
104+
)
105+
self.interface.intrinsic.height = height[1]
106+
else: # pragma: no-cover-if-gtk3
107+
print(
108+
"[DEBUG TextInput] REHINT",
109+
self,
110+
self.native.get_preferred_size()[1].width,
111+
self.native.get_preferred_size()[1].height,
112+
)
113+
min_size, size = self.native.get_preferred_size()
114+
115+
self.interface.intrinsic.width = at_least(
116+
max(min_size.width, self.interface._MIN_WIDTH)
117+
)
118+
self.interface.intrinsic.height = min_size.height
73119

74120
def set_error(self, error_message):
75121
self.native.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "error")

gtk/tests_backend/widgets/textinput.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pytest
22

33
from toga.constants import JUSTIFY, LEFT
4-
from toga_gtk.libs import GTK_VERSION, Gtk
4+
from toga_gtk.libs import Gtk
55

66
from .base import SimpleProbe
77
from .properties import toga_x_text_align
@@ -10,9 +10,6 @@
1010
class TextInputProbe(SimpleProbe):
1111
native_class = Gtk.Entry
1212

13-
if GTK_VERSION >= (4, 0, 0):
14-
pytest.skip("GTK4 doesn't support text input yet")
15-
1613
@property
1714
def value(self):
1815
return (

0 commit comments

Comments
 (0)