Skip to content

Commit a24eac1

Browse files
committed
fix: exclude Text and Listbox height from DPI scaling
1 parent cd03c1b commit a24eac1

File tree

2 files changed

+83
-11
lines changed

2 files changed

+83
-11
lines changed

tests/test_dpi.py

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,10 +1384,16 @@ def helper__test_tkinter_constructor_patch(tk_class, manager, scaling_factor, **
13841384
setattr(tk_class, '__init__', mock_original_init)
13851385

13861386
# Apply the patch
1387-
# Handle special case for Button
1387+
# Handle special cases for Button, Text, and Listbox
13881388
if tk_class.__name__ == 'Button':
13891389
patch_method = getattr(manager, '_patch_button_constructor')
13901390
patch_method(scaling_factor)
1391+
elif tk_class.__name__ == 'Text':
1392+
patch_method = getattr(manager, '_patch_text_constructor')
1393+
patch_method(scaling_factor)
1394+
elif tk_class.__name__ == 'Listbox':
1395+
patch_method = getattr(manager, '_patch_listbox_constructor')
1396+
patch_method(scaling_factor)
13911397
else:
13921398
# Use unified patching method
13931399
patch_method = getattr(manager, '_apply_standard_widget_patch')
@@ -1403,7 +1409,10 @@ def helper__test_tkinter_constructor_patch(tk_class, manager, scaling_factor, **
14031409
# Calculate expected values
14041410
expected_kwargs = {}
14051411
for key, value in test_kwargs.items():
1406-
if key in ['padx', 'pady', 'bd', 'wraplength', 'width', 'height']:
1412+
# Text and Listbox height should not be scaled (it's line count, not pixels)
1413+
if key == 'height' and tk_class.__name__ in ('Text', 'Listbox'):
1414+
expected_kwargs[key] = value
1415+
elif key in ['padx', 'pady', 'bd', 'wraplength', 'width', 'height']:
14071416
if isinstance(value, tuple):
14081417
expected_kwargs[key] = tuple(int(v * scaling_factor) for v in value)
14091418
else:
@@ -1419,9 +1428,16 @@ def helper__test_tkinter_constructor_patch_no_scaling(tk_class, manager, scaling
14191428
"""Helper function to test tkinter constructor patching without scaling parameters."""
14201429
with TkinterMethodPatchContext(tk_class, '__init__', manager, scaling_factor) as patch_ctx:
14211430
# Apply the patch
1431+
# Handle special cases for Button, Text, and Listbox
14221432
if tk_class.__name__ == 'Button':
14231433
patch_method = getattr(manager, '_patch_button_constructor')
14241434
patch_method(scaling_factor)
1435+
elif tk_class.__name__ == 'Text':
1436+
patch_method = getattr(manager, '_patch_text_constructor')
1437+
patch_method(scaling_factor)
1438+
elif tk_class.__name__ == 'Listbox':
1439+
patch_method = getattr(manager, '_patch_listbox_constructor')
1440+
patch_method(scaling_factor)
14251441
else:
14261442
patch_method = getattr(manager, '_apply_standard_widget_patch')
14271443
patch_method(tk_class, scaling_factor)
@@ -2761,6 +2777,8 @@ def test_patch_label_frame_constructor(self):
27612777
# Text tests
27622778
(tk.Text, 1.5, {"bd": 4}, {"bd": 6}),
27632779
(tk.Text, 2.0, {"bd": 2}, {"bd": 4}),
2780+
(tk.Text, 2.0, {"height": 8}, {"height": 8}), # height is line count, not scaled
2781+
(tk.Text, 1.5, {"height": 10, "bd": 2}, {"height": 10, "bd": 3}),
27642782
# Checkbutton tests
27652783
(tk.Checkbutton, 2.0, {"bd": 2}, {"bd": 4}),
27662784
(tk.Checkbutton, 1.5, {"bd": 3}, {"bd": 4}),
@@ -2770,6 +2788,8 @@ def test_patch_label_frame_constructor(self):
27702788
# Listbox tests
27712789
(tk.Listbox, 2.0, {"bd": 1}, {"bd": 2}),
27722790
(tk.Listbox, 1.5, {"bd": 4}, {"bd": 6}),
2791+
(tk.Listbox, 2.0, {"height": 5}, {"height": 5}), # height is line count, not scaled
2792+
(tk.Listbox, 1.5, {"height": 3, "bd": 2}, {"height": 3, "bd": 3}),
27732793
# Spinbox tests
27742794
(tk.Spinbox, 1.5, {"bd": 4}, {"bd": 6}),
27752795
(tk.Spinbox, 2.0, {"bd": 2}, {"bd": 4}),
@@ -2834,9 +2854,9 @@ def test_patch_label_constructor(self):
28342854
_test_tkinter_constructor_patch_with_context(manager, tk.Label, '_apply_standard_widget_patch', 2.0)
28352855

28362856
def test_patch_text_constructor(self):
2837-
"""Test _apply_standard_widget_patch for Text."""
2857+
"""Test _patch_text_constructor for Text."""
28382858
manager = create_dpi_manager_for_test()
2839-
_test_tkinter_constructor_patch_with_context(manager, tk.Text, '_apply_standard_widget_patch', 2.0)
2859+
_test_tkinter_constructor_patch_with_context(manager, tk.Text, '_patch_text_constructor', 2.0)
28402860

28412861

28422862
def test_patch_checkbutton_constructor(self):
@@ -2852,9 +2872,9 @@ def test_patch_radiobutton_constructor(self):
28522872

28532873

28542874
def test_patch_listbox_constructor(self):
2855-
"""Test _apply_standard_widget_patch for Listbox."""
2875+
"""Test _patch_listbox_constructor for Listbox."""
28562876
manager = create_dpi_manager_for_test()
2857-
_test_tkinter_constructor_patch_with_context(manager, tk.Listbox, '_apply_standard_widget_patch', 2.0)
2877+
_test_tkinter_constructor_patch_with_context(manager, tk.Listbox, '_patch_listbox_constructor', 2.0)
28582878

28592879

28602880
def test_patch_spinbox_constructor(self):
@@ -3275,12 +3295,23 @@ def test_text_constructor_patch_with_padding(self, manager):
32753295
self._test_constructor_patch(
32763296
manager=manager,
32773297
widget_class=tk.Text,
3278-
patch_method='_apply_standard_widget_patch',
3298+
patch_method='_patch_text_constructor',
32793299
patch_path='tkinter.Text.__init__',
32803300
input_kwargs={'padx': 10, 'pady': 20, 'bd': 2},
32813301
expected_kwargs={'padx': 20, 'pady': 40, 'bd': 4} # Unified rule: all scale
32823302
)
32833303

3304+
def test_text_constructor_patch_with_height(self, manager):
3305+
"""Test Text constructor patching with height (should not be scaled)."""
3306+
self._test_constructor_patch(
3307+
manager=manager,
3308+
widget_class=tk.Text,
3309+
patch_method='_patch_text_constructor',
3310+
patch_path='tkinter.Text.__init__',
3311+
input_kwargs={'height': 8, 'bd': 2},
3312+
expected_kwargs={'height': 8, 'bd': 4} # height is line count, not scaled
3313+
)
3314+
32843315
def test_checkbutton_constructor_patch_with_padding(self, manager):
32853316
"""Test Checkbutton constructor patching with padding."""
32863317
self._test_constructor_patch(
@@ -3308,12 +3339,23 @@ def test_listbox_constructor_patch_with_padding(self, manager):
33083339
self._test_constructor_patch(
33093340
manager=manager,
33103341
widget_class=tk.Listbox,
3311-
patch_method='_apply_standard_widget_patch',
3342+
patch_method='_patch_listbox_constructor',
33123343
patch_path='tkinter.Listbox.__init__',
33133344
input_kwargs={'padx': 10, 'pady': 20, 'bd': 2},
33143345
expected_kwargs={'padx': 20, 'pady': 40, 'bd': 4} # Unified rule: all scale
33153346
)
33163347

3348+
def test_listbox_constructor_patch_with_height(self, manager):
3349+
"""Test Listbox constructor patching with height (should not be scaled)."""
3350+
self._test_constructor_patch(
3351+
manager=manager,
3352+
widget_class=tk.Listbox,
3353+
patch_method='_patch_listbox_constructor',
3354+
patch_path='tkinter.Listbox.__init__',
3355+
input_kwargs={'height': 5, 'bd': 2},
3356+
expected_kwargs={'height': 5, 'bd': 4} # height is line count, not scaled
3357+
)
3358+
33173359
def test_spinbox_constructor_patch_with_padding(self, manager):
33183360
"""Test Spinbox constructor patching with padding."""
33193361
self._test_constructor_patch(

tkface/win/dpi.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -741,13 +741,15 @@ def _patch_widget_constructors(self, scaling_factor: ScalingFactor) -> None:
741741
"""Patch widget constructors with scaling."""
742742
self._patch_standard_widgets(scaling_factor)
743743
self._patch_button_constructor(scaling_factor)
744+
self._patch_text_constructor(scaling_factor)
745+
self._patch_listbox_constructor(scaling_factor)
744746

745747
def _patch_standard_widgets(self, scaling_factor: ScalingFactor) -> None:
746748
"""Patch standard widget constructors with scaling."""
747-
# Standard tk widgets (Button excluded - has special handling)
749+
# Standard tk widgets (Button, Text, Listbox excluded - have special handling)
748750
tk_widgets = [
749-
tk.LabelFrame, tk.Frame, tk.Entry, tk.Label, tk.Text,
750-
tk.Checkbutton, tk.Radiobutton, tk.Listbox, tk.Spinbox,
751+
tk.LabelFrame, tk.Frame, tk.Entry, tk.Label,
752+
tk.Checkbutton, tk.Radiobutton, tk.Spinbox,
751753
tk.Scale, tk.Scrollbar, tk.Canvas, tk.Menu, tk.Menubutton,
752754
]
753755

@@ -836,6 +838,34 @@ def button_handler(self, parent, kwargs, original, scaling_factor, manager):
836838

837839
self._patch_widget_constructor(tk.Button, scaling_factor, "tk.Button.__init__", button_handler)
838840

841+
def _patch_text_constructor(self, scaling_factor: ScalingFactor) -> None:
842+
"""Patch the Text constructor with scaling (excluding height which specifies line count)."""
843+
def text_handler(self, parent, kwargs, original, scaling_factor, manager):
844+
# Use unified method but exclude height from scaling (height is line count, not pixels)
845+
scaled_kwargs = manager._scale_widget_kwargs(
846+
kwargs, scaling_factor, scale_padding=True, scale_length=True
847+
)
848+
# Restore original height value (line count should not be scaled)
849+
if "height" in kwargs:
850+
scaled_kwargs["height"] = kwargs["height"]
851+
return original(self, parent, **scaled_kwargs)
852+
853+
self._patch_widget_constructor(tk.Text, scaling_factor, "tk.Text.__init__", text_handler)
854+
855+
def _patch_listbox_constructor(self, scaling_factor: ScalingFactor) -> None:
856+
"""Patch the Listbox constructor with scaling (excluding height which specifies line count)."""
857+
def listbox_handler(self, parent, kwargs, original, scaling_factor, manager):
858+
# Use unified method but exclude height from scaling (height is line count, not pixels)
859+
scaled_kwargs = manager._scale_widget_kwargs(
860+
kwargs, scaling_factor, scale_padding=True, scale_length=True
861+
)
862+
# Restore original height value (line count should not be scaled)
863+
if "height" in kwargs:
864+
scaled_kwargs["height"] = kwargs["height"]
865+
return original(self, parent, **scaled_kwargs)
866+
867+
self._patch_widget_constructor(tk.Listbox, scaling_factor, "tk.Listbox.__init__", listbox_handler)
868+
839869
def _patch_treeview_methods(self, scaling_factor: ScalingFactor) -> None:
840870
"""Patch TreeView methods with scaling."""
841871
def _apply_treeview_patches():

0 commit comments

Comments
 (0)