Getting the default border colour for the current theme?

I have a bunch of GtK.Entrys that are basically used as display widgets. Setting set_editable(False) and set_has_frame(False) and then adding them into a Gtk.Viewport to draw a nice subtle border. I recently started porting to GTK3 (yes I’m late!) and thought about simplifying this by removing the outer viewport and using some CSS to draw the border instead.

Calling set_has_frame(False) adds the flat CSS class and the entry looks fine for my usecase, except for the custom border. I tried adding the frame CSS class which seems to draw the Gtk.Viewport border, but doesn’t work on the flat entry. So it looks like I have to set the border colour myself. The problem is choosing the right colour. There are some other widgets that draw a frame (Gtk.Frame, Gtk.Viewport) and I’d like to be consistent with those throughout my application.

Is there are reliable way to get and use the current theme’s border/frame colour to use in my own CSS?

If not, can someone help with combining the flat and frame classes on a Gtk.Entry?

Here’s a runnable example that shows the old way of how I’ve been doing it and the plain Gtk.Entry way that should match the look.

#!/usr/bin/env python3

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from gi.repository import Gdk


CSS = b"""

"""

screen = Gdk.Screen.get_default()
style_context = Gtk.StyleContext()
provider = Gtk.CssProvider()
provider.load_from_data(CSS)
style_context.add_provider_for_screen(screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

entry_old = Gtk.Entry()
entry_old.set_editable(False)
entry_old.set_has_frame(False)
viewport_old = Gtk.Viewport()
viewport_old.add(entry_old)

entry_new = Gtk.Entry()
entry_new.set_editable(False)
entry_new.set_has_frame(False)
entry_new.get_style_context().add_class("frame")

box = Gtk.Box(spacing=6, orientation=Gtk.Orientation.VERTICAL)
box.set_margin_left(8)
box.set_margin_right(8)
box.pack_start(Gtk.Label("Old entry"), False, False, 0)
box.pack_start(viewport_old, False, False, 0)
box.pack_start(Gtk.Label("New entry"), False, False, 0)
box.pack_start(entry_new, False, False, 0)

win = Gtk.Window()
win.connect("delete-event", Gtk.main_quit)
win.set_default_size(400, 400)
win.add(box)
win.show_all()
Gtk.main()

If you look at the /usr/share/themes/*/gtk-3.x/gtk.css file for any theme other than Adwaita (which is built in to Gtk, so it has no CSS file), you can see the color names that the themes use, though I have no idea whether they’re documented anywhere.

And, of course, looking at /usr/share/themes/Breeze/gtk-3.20/gtk.css I see that while it defines names like @borders for theme colors, it also styles its .entry widgets with a custom color that doesn’t use any of the defined theming:

/* GTK NAMED COLORS
   ----------------
   use responsibly! */
/*
widget text/foreground color */
@define-color theme_fg_color #232627;
/*
text color for entries, views and content in general */
@define-color theme_text_color #232627;
/*
widget base background color */
@define-color theme_bg_color #eff0f1;
/*
text widgets and the like base background color */
@define-color theme_base_color #fcfcfc;


/*
widgets main borders color */
@define-color borders #bcbebf;
/*
widgets main borders color on backdrop windows */
@define-color unfocused_borders #bcbebf;
/*
widgets main borders color insensitive */
@define-color insensitive_borders rgba(170, 173, 174, 0.35);


/****************
 * Text Entries *
 ****************/
spinbutton:not(.vertical),
entry {
  min-height: 30px;
  padding-left: 8px;
  padding-right: 8px;
  border: 1px solid;
  border-radius: 3px;
  transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
  color: #232627;
  border-color: #bcbebf;
  background-color: #fcfcfc;
  box-shadow: none; }

treeview entry.flat, treeview entry {
  border-radius: 0;
  background-image: none;
  background-color: #fcfcfc; }
  treeview entry.flat:focus, treeview entry:focus {
    border-color: #3daee9; }

ETA: Having re-read, it uses the same colors, looks like… just doesn’t reference them using the defined names. So I guess as long as they’re consistent on that, you can reference colors like @borders or @theme_bg_color to match them.

Thanks, that’s what I was looking for. I found the @theme_*_color before, but hadn’t seen the @borders. Looks like all themes that I tested (with GtkInspector, what an awesome tool!) define it.

For reference, here’s the code that gives me the result I was looking for:

CSS = b"""
.my-entry {
  border-color: @borders;
}
"""
entry = Gtk.Entry()
entry.set_editable(False)
entry.set_has_frame(False)
entry.get_style_context().add_class("my-entry")
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.