Skip to content

Commit 12bd886

Browse files
committed
touchy: keep the window within the monitor
Touchy has no scrolling, so its window minimum is the sum of every child's request with nothing bounding it to the screen: the default Sans 18 font alone wants ~1280x830 (off a 1024x768 display), and reloading the tool table has been reported to double the height off screen with no way back. Wrap the content in a GtkScrolledWindow and bound the window to the monitor work area via a max-size geometry hint. The scroller's min-content is set to the natural size capped to the work area, so the window opens at its natural size and only scrolls the overflow. On a display large enough nothing scrolls and behaviour is unchanged.
1 parent 888cb94 commit 12bd886

1 file changed

Lines changed: 64 additions & 0 deletions

File tree

src/emc/usr_intf/touchy/touchy.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ def __init__(self, inifile):
107107
self.wTree.get_object('MainWindow').set_can_focus(True)
108108
self.wTree.get_object('MainWindow').grab_focus()
109109

110+
# Stop the window growing past the screen (see method).
111+
self._constrain_to_monitor()
112+
110113
self.num_mdi_labels = 11
111114
self.num_filechooser_labels = 11
112115
self.num_listing_labels = 20
@@ -627,6 +630,67 @@ def change_theme(self, b):
627630
settings = Gtk.Settings.get_default()
628631
settings.set_string_property("gtk-theme-name", theme, "")
629632

633+
def _constrain_to_monitor(self):
634+
# Wrap the content in a scroller so the window can be bounded to the
635+
# monitor (touchy has no scrolling otherwise, so the window grows
636+
# past the screen when a panel does). Best-effort.
637+
try:
638+
win = self.wTree.get_object("MainWindow")
639+
child = win.get_child()
640+
if child is None or isinstance(child, Gtk.ScrolledWindow):
641+
return
642+
scroller = Gtk.ScrolledWindow()
643+
scroller.set_policy(Gtk.PolicyType.AUTOMATIC,
644+
Gtk.PolicyType.AUTOMATIC)
645+
win.remove(child)
646+
scroller.add(child)
647+
viewport = scroller.get_child()
648+
if isinstance(viewport, Gtk.Viewport):
649+
viewport.set_shadow_type(Gtk.ShadowType.NONE)
650+
win.add(scroller)
651+
scroller.show_all()
652+
# Size on map, once the monitor and final fonts are known.
653+
self._fitted = False
654+
win.connect("map-event", self._fit_to_monitor, scroller, child)
655+
except Exception:
656+
pass
657+
658+
def _fit_to_monitor(self, win, event, scroller, child):
659+
if self._fitted:
660+
return False
661+
self._fitted = True
662+
# Bound the window to the work area now; size the scroller on idle,
663+
# once layout has settled and the natural size is final.
664+
try:
665+
display = win.get_display()
666+
gdkwin = win.get_window()
667+
if gdkwin is not None:
668+
monitor = display.get_monitor_at_window(gdkwin)
669+
else:
670+
monitor = display.get_primary_monitor()
671+
if monitor is None:
672+
monitor = display.get_monitor(0)
673+
area = monitor.get_workarea()
674+
hints = Gdk.Geometry()
675+
hints.max_width = area.width
676+
hints.max_height = area.height
677+
win.set_geometry_hints(None, hints, Gdk.WindowHints.MAX_SIZE)
678+
GLib.idle_add(self._size_scroller, scroller, child, area)
679+
except Exception:
680+
pass
681+
return False
682+
683+
def _size_scroller(self, scroller, child, area):
684+
try:
685+
natural = child.get_preferred_size()[1]
686+
scroller.set_min_content_width(min(natural.width, area.width))
687+
scroller.set_max_content_width(area.width)
688+
scroller.set_min_content_height(min(natural.height, area.height))
689+
scroller.set_max_content_height(area.height)
690+
except Exception:
691+
pass
692+
return False
693+
630694
def setfont(self):
631695
# buttons
632696
for i in ["1", "2", "3", "4", "5", "6", "7",

0 commit comments

Comments
 (0)