Skip to content

touchy: replace deprecated font and colour overrides with CSS#4133

Merged
hansu merged 3 commits into
LinuxCNC:masterfrom
grandixximo:touchy-override-font
Jun 14, 2026
Merged

touchy: replace deprecated font and colour overrides with CSS#4133
hansu merged 3 commits into
LinuxCNC:masterfrom
grandixximo:touchy-override-font

Conversation

@grandixximo

Copy link
Copy Markdown
Contributor

GTK deprecated Gtk.Widget.override_font() and modify_fg() in 3.16. Touchy uses them throughout setfont() to set every display font and the per-coordinate DRO text colours, so it logs deprecation warnings.

This tags the widgets with style classes once and drives the fonts and colours from a single GtkCssProvider on the screen, rebuilt whenever a font or colour preference changes. A Pango font description is translated to CSS font properties, and stored colours are normalised through Gdk.RGBA. The rendered result is unchanged.

Tested with the ui-smoke touchy tests and by hand: the fonts render identically (buttons, DRO, tab labels, handwheel), and the per-coordinate DRO colours still apply (verified with rel/abs/dtg set to blue/red/green).

The modify_bg() calls in filechooser, listing and mdi are a separate selection-highlight pattern and left for a follow-up.

@hansu

hansu commented Jun 5, 2026

Copy link
Copy Markdown
Member

I would suggest to add property "name" to the widgets in the touchy.glade file and then add a block where all CSS styles are defined like I did in Gmoccapy:

<property name="name">gcode_edit</property>

#gcode_edit {
padding: 3px;
margin: 1px;
}

This would not require so many changes in the touchy.py file I guess.

BUT for that the touchy.glade must first be converted to Gtk3. I tried this yesterday, but the result was not satisfactory - all the button were smaller and did not fill the space so I postponed that for the moment...

@grandixximo

Copy link
Copy Markdown
Contributor Author

Thanks Hans. I looked at the gmoccapy approach and it's clean for fixed styling.

The difference in touchy is that its four display fonts (control, DRO, error, listing) and the DRO text colours are user preferences: set on the Preferences tab, saved to ~/.touchy_preferences, and changeable at runtime. So the CSS can't be a static block; it has to be generated from the current font descriptions and reloaded whenever a preference changes. That dynamic part (_font_to_css / _reload_font_css) is most of the diff and is needed regardless of how the widgets are selected.

The tagging itself reuses the font-group lists setfont() already had, so the net touchy.py change is small (mostly swapping override_font/modify_fg for one style class). I'm glad to use name properties in the glade instead of programmatic classes if you prefer; for per-group fonts a shared class is just more concise than naming every widget.

I agree the proper end state is a full GTK3 glade with the styling defined there, but that's the larger conversion you hit the button-sizing trouble with, so I scoped this PR to just removing the deprecated calls on the current glade. The rendered result is unchanged (verified the fonts and the rel/abs/dtg DRO colours).

Happy to go whichever way you and the maintainers prefer.

@hansu

hansu commented Jun 5, 2026

Copy link
Copy Markdown
Member

As far as I can see self._tag() is only applied to the widgets once in during init so I would prefer that as name property in the glade file. The rest is fine.

Happy to go whichever way you and the maintainers prefer.

Unfortunately I don't think we have a maintainer currently.

@hansu hansu mentioned this pull request Jun 5, 2026
@hansu hansu added the Touchy label Jun 5, 2026

@hansu hansu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just mark it here as "changes needed" to keep the overview =)

Comment thread src/emc/usr_intf/touchy/touchy.py Outdated
w = self.wTree.get_object(i)
if w:
w.override_font(self.control_font)
self._tag(w, "touchy_control")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to name property in glade file (after merge of #4135)

@grandixximo

Copy link
Copy Markdown
Contributor Author

Agreed on the order. I tested #4135 in a sim container and it renders correctly in GTK3 (the status grid is tidy now). At default Sans 18 it is still wider than a small screen until #4131's fitting is applied on top, which lines up with your 718x596, so #4135 then #4131 then #4133 makes sense.

For #4133 I'll move the widget identification into the glade as name properties on your converted file and keep the dynamic CSS generation for the user-set fonts and colours, then rebase both PRs onto #4135.

@grandixximo grandixximo marked this pull request as draft June 6, 2026 03:46
@grandixximo

Copy link
Copy Markdown
Contributor Author

@hansu before I commit a large diff, one snag with moving the tags into the glade as name properties.

A widget has a single name, but the DRO readouts need two tags layered: the shared DRO font, plus an optional per-column colour (rel/abs/dtg) applied only when the user sets a non-default colour. The code does this with two style classes on one widget:

self._tag(w, "touchy_dro")   # font, always
self._tag(w, "touchy_rel")   # colour, only if non-default

name can't carry both, so a literal version has to collapse each DRO subgroup into one name whose rule repeats the font and adds the colour. It works, but it is less clean. Scale also matters: the tags cover ~150 widgets, so naming them all is a ~150-line glade diff replacing ~15 lines of code.

Two options:

  • B (keep code tagging): per-group style classes applied once in setfont(). A widget can hold multiple classes, so the DRO font+colour layering stays natural and the grouping is a few readable loops. The deprecated override_font/modify_fg calls are gone either way.
  • C (hybrid): name the simple single-tag groups (control, listing) in the glade, keep code tagging only for the DRO where the layering needs more than one class.

I lean to B for maintainability, but happy to do C if you would rather see control/listing declared in the glade. Which do you prefer?

@hansu

hansu commented Jun 7, 2026

Copy link
Copy Markdown
Member

I lean to B for maintainability, but happy to do C if you would rather see control/listing declared in the glade. Which do you prefer?

Let me have closer look at it. But it wouldn't be before Wednesday unfortunately.

@grandixximo grandixximo requested a review from hansu June 12, 2026 06:45
@hansu

hansu commented Jun 12, 2026

Copy link
Copy Markdown
Member

Sorry I forgot that...

@grandixximo

Copy link
Copy Markdown
Contributor Author

That's ok, wouldn't have passed the CI anyhow on Wednesday...

@hansu

hansu commented Jun 13, 2026

Copy link
Copy Markdown
Member

I thought it like this d5bd26e

but then you need to have the font duplicated in the CSS:

#touchy_dro { font: ...; }
#touchy_rel { color: ...; font: ...; }
#touchy_abs { color: ...; font: ...; }
#touchy_dtg { color: ...; font: ...; }

So I guess it's a matter of taste. One makes the code shorter the other is better style I guess. Both is okay for me.

But If we keep your version

I would rename the _tag() function to a more meaningful name, maybe like this:

     def _add_style_class(self, widget, name):
            # Add a style class once; the shared CSS provider carries the font
            # and colour for that class.
            if widget is not None:
                context = widget.get_style_context()
                if not context.has_class(name):
                    context.add_class(name)

GTK deprecated Gtk.Widget.override_font() and modify_fg() in 3.16. Touchy
used them throughout setfont() to set every display font and the
per-coordinate DRO text colours, logging deprecation warnings.

Tag the widgets with style classes once and drive the fonts and colours
from a single GtkCssProvider on the screen, rebuilt whenever a font or
colour preference changes. A Pango font description is translated to CSS
font properties and stored colours are normalised through Gdk.RGBA. The
rendered result is unchanged.

The modify_bg() calls in filechooser, listing and mdi are a separate
selection-highlight pattern and are left for a follow-up.
The default dro_font "FreeMono 10 Pitch Bold 16" parses to the Pango
family "FreeMono 10 Pitch". The preference font buttons use
use-font=True, so GtkFontButton renders its label in that font and
emits the family as unquoted CSS, which GTK rejects with
"Junk at end of value for font-family" (the parse warning in LinuxCNC#4068).

"FreeMono 10 Pitch" is not a real family (Pango already fell back to
monospace), so drop the legacy "10 Pitch" token and default to
"FreeMono Bold 16". On a fresh profile this clears the warning.
Per review on LinuxCNC#4133: a more descriptive name for the helper that
adds a style class once. No behavior change.
@grandixximo grandixximo force-pushed the touchy-override-font branch from f20057e to aada117 Compare June 14, 2026 01:31
@grandixximo grandixximo marked this pull request as ready for review June 14, 2026 01:31
@grandixximo

Copy link
Copy Markdown
Contributor Author

@hansu went with option B and renamed _tag to _add_style_class as you suggested. Rebased onto current master (post #4135), so this now applies on top of the GTK3 conversion. Marked ready for review.

@hansu hansu merged commit 4809445 into LinuxCNC:master Jun 14, 2026
16 checks passed
@grandixximo grandixximo deleted the touchy-override-font branch June 15, 2026 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants