Skip to content

Commit eeb246e

Browse files
committed
fix(gui): normalize tk_scaling in ProgressWindow and defer focus_force to prevent segfault
- Normalize tk_scaling with * 72.0/96.0 and add max(1.0, ...) floor in ProgressWindow to match BaseWindow._get_dpi_scaling_factor behaviour - Use calculate_scaled_geometry() in VehicleProjectCreatorWindow instead of inline scaling to keep geometry logic centralized - Defer focus_force() via after(1, ...) in PopupWindow to avoid a segfault in Python 3.9 on Linux/X11 in headless CI environments - Call update_idletasks() before winfo_width/height in GUI test to prevent flaky 1px assertions before geometry is realized Addresses review comments from PR #1394
1 parent 31fb9a2 commit eeb246e

File tree

4 files changed

+7
-5
lines changed

4 files changed

+7
-5
lines changed

ardupilot_methodic_configurator/frontend_tkinter_progress_window.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ def __init__( # pylint: disable=too-many-arguments, too-many-positional-argumen
4646
try:
4747
dpi = self.progress_window.winfo_fpixels("1i")
4848
tk_scaling = float(self.progress_window.tk.call("tk", "scaling"))
49-
dpi_scaling_factor = max(dpi / 96.0, tk_scaling)
49+
normalized_tk_scaling = tk_scaling * 72.0 / 96.0
50+
dpi_scaling_factor = max(1.0, dpi / 96.0, normalized_tk_scaling)
5051
except (tk.TclError, AttributeError):
5152
dpi_scaling_factor = 1.0
5253
self.progress_window.geometry(f"{round(width * dpi_scaling_factor)}x{round(height * dpi_scaling_factor)}")

ardupilot_methodic_configurator/frontend_tkinter_project_creator.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,7 @@ def template_selection_callback(_widget: "DirectorySelectionWidgets") -> str:
135135

136136
# Set dynamic window size based on number of settings
137137
window_height = 250 + (len(settings_metadata) * 23)
138-
self.root.geometry(
139-
f"{round(800 * self.dpi_scaling_factor)}x{round(window_height * self.dpi_scaling_factor)}"
140-
) # Set the window size
138+
self.root.geometry(self.calculate_scaled_geometry(800, window_height)) # Set the window size
141139
self.center_window_on_screen(self.root)
142140

143141
for setting_name, metadata in settings_metadata.items():

ardupilot_methodic_configurator/frontend_tkinter_usage_popup_window.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ def finalize_setup_popupwindow(
114114
popup_window.root.deiconify()
115115
popup_window.root.lift()
116116
popup_window.root.update() # Ensure the window is fully rendered before setting focus
117-
popup_window.root.focus_force()
117+
# Defer focus_force to after the event loop has processed the deiconify/lift,
118+
# avoiding a segfault in Python 3.9 on Linux (X11) in headless environments.
119+
popup_window.root.after(1, popup_window.root.focus_force)
118120

119121
# On macOS, grab_set() causes UI freeze (issue #1264), so skip it
120122
# On Windows/Linux, make the popup modal and give it focus

tests/gui_frontend_tkinter_parameter_editor.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ def test_show_about_window(self, mocker) -> None: # pylint: disable=too-many-lo
158158
# Check window properties
159159
assert about_window.title() == "About"
160160
# Check that geometry has positive dimensions (exact size depends on DPI scaling)
161+
about_window.update_idletasks()
161162
win_width = about_window.winfo_width()
162163
win_height = about_window.winfo_height()
163164
assert win_width >= 650, f"Window width {win_width} should be at least 650px (unscaled)"

0 commit comments

Comments
 (0)