From e2fc45e03b69cd516cfc9c41f8775bdb0948b56d Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 10 Jun 2026 18:45:19 +0800 Subject: [PATCH 1/3] touchy: fix maximize with a saved window geometry window.maximize() is a GTK2 leftover; a GTK3 GtkWindow has no .window attribute, so starting with window_geometry and window_force_max set in ~/.touchy_preferences crashed at startup. Call maximize() on the window itself, as the default-geometry path already does. --- src/emc/usr_intf/touchy/touchy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emc/usr_intf/touchy/touchy.py b/src/emc/usr_intf/touchy/touchy.py index 82a9a4aa173..44cd17d2ec8 100755 --- a/src/emc/usr_intf/touchy/touchy.py +++ b/src/emc/usr_intf/touchy/touchy.py @@ -178,7 +178,7 @@ def __init__(self, inifile): else: self.wTree.get_object("MainWindow").parse_geometry(self.window_geometry) if self.window_max: - self.wTree.get_object("MainWindow").window.maximize() + self.wTree.get_object("MainWindow").maximize() self.invisible_cursor = self.prefs.getpref('invisible_cursor', 0) if self.invisible_cursor: From 5226f3ddfe776dc47db52c28bb2b88ec8388e92b Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 10 Jun 2026 18:45:19 +0800 Subject: [PATCH 2/3] touchy: let a saved window geometry win over fit-to-monitor The map-time resize to the content's natural size overrode a user-saved window_geometry preference, so the saved size was never honored. Skip the natural-size resize when an explicit geometry is set; the scroller still bounds the window to the work area. --- src/emc/usr_intf/touchy/touchy.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/emc/usr_intf/touchy/touchy.py b/src/emc/usr_intf/touchy/touchy.py index 44cd17d2ec8..805095a0026 100755 --- a/src/emc/usr_intf/touchy/touchy.py +++ b/src/emc/usr_intf/touchy/touchy.py @@ -814,10 +814,12 @@ def _fit_to_monitor(self, win, event, scroller, child): scroller.set_max_content_width(area.width) scroller.set_max_content_height(area.height) # Open at the content size, capped to the screen; this avoids an - # off-screen window without forcing a screen-sized minimum. - nat = child.get_preferred_size()[1] - win.resize(min(nat.width, area.width), - min(nat.height, area.height)) + # off-screen window without forcing a screen-sized minimum. A + # user-saved geometry (window_geometry pref) takes precedence. + if self.window_geometry == "default": + nat = child.get_preferred_size()[1] + win.resize(min(nat.width, area.width), + min(nat.height, area.height)) GLib.idle_add(self._offer_fit, child, area) except Exception: pass From 0a6c914136d9fdf45a7d2c641ba1a7ec2af64971 Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Wed, 10 Jun 2026 18:45:19 +0800 Subject: [PATCH 3/3] touchy: stop MDI, listing and file panes resizing with content The MDI word labels, the G-code listing and the file chooser names grow with their text, so typing a long number resized the number pad pane and a long G-code line pushed the page/start-point controls out of view. Wrap each of those label columns in a horizontal scroller (with the existing drag-to-pan) so long content scrolls in place and the layout never moves. --- src/emc/usr_intf/touchy/touchy.py | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/emc/usr_intf/touchy/touchy.py b/src/emc/usr_intf/touchy/touchy.py index 805095a0026..80d26bc0465 100755 --- a/src/emc/usr_intf/touchy/touchy.py +++ b/src/emc/usr_intf/touchy/touchy.py @@ -706,6 +706,36 @@ def _wrap_notebook_pages(self): if current >= 0: nb.set_current_page(current) + def _wrap_hscroll(self, name): + # Labels showing typed MDI values, G-code lines or file names grow + # with their text, which widens the pane and pushes the controls + # beside it out of view. Wrap each label column in a horizontal + # scroller so long content scrolls (drag to pan) instead of + # stretching the layout. + w = self.wTree.get_object(name) + if w is None: + return + parent = w.get_parent() + if parent is None or isinstance(parent, Gtk.Viewport): + return + props = {} + for pspec in parent.list_child_properties(): + props[pspec.name] = parent.child_get_property(w, pspec.name) + scroller = Gtk.ScrolledWindow() + scroller.set_policy(Gtk.PolicyType.AUTOMATIC, + Gtk.PolicyType.NEVER) + scroller.set_propagate_natural_height(True) + parent.remove(w) + scroller.add(w) + viewport = scroller.get_child() + if isinstance(viewport, Gtk.Viewport): + viewport.set_shadow_type(Gtk.ShadowType.NONE) + parent.add(scroller) + for pname, value in props.items(): + parent.child_set_property(scroller, pname, value) + self._enable_drag_scroll(scroller) + scroller.show_all() + def _enable_drag_scroll(self, scroller): # Touchy is a touchscreen UI, so let the user drag the content to # scroll it (finger or mouse), not just the wheel/scrollbar. A drag @@ -748,6 +778,11 @@ def _constrain_to_monitor(self): # Wrap the content in a scroller so the window can be bounded to the # monitor; touchy has no scrolling otherwise and grows past the screen. try: + # MDI words, the G-code listing and the file chooser names + # hold user-sized text; scroll them in place so typing or + # loading a file never relayouts the neighboring panes. + for name in ("vbox11", "table16", "table17"): + self._wrap_hscroll(name) self._wrap_notebook_pages() win = self.wTree.get_object("MainWindow") child = win.get_child()