Eclipse, Dark theme and Gtk. What Eclipse can theme and what needs to be themed by the OS.

 

About

I’m an SWT developer on the Gtk side.

Recently I’ve done a fair bit of work with Eclipse’s dark theme and Gtk’s CSS. (E.g fixing background of button and combo). As such I’ve come across what is do-able in SWT and what is not.

 

The issue with composed GtkWidgets

In SWT, we can theme individual GtkWidgets with gtk_context_add_provider(widgetProvider, css) . E.g basic labels, buttons. This works well for basic widgets.

However, some gtk widgets are composed of multiple nested widgets. E.g: GtkComboBoxText

GtkComboBoxText
— GtkToggleButton
— GtkTreeMenu
— GtkCellView
— etc..

The issue is that the CSS that we apply only get’s applied to the top-level widget and not always recursively to all it’s child widgets. (Please see 1* in appendix)

With such widgets, we can sometimes use gtk_bin_get_child() to get one of the nested components and run gtk_context_add_provider(..) on that, but this doesn’t give us access to all nested components. (bin_get_child returns only one child).
Sometimes we can hack a bit and with gtk_container_forall(..) access the child widgets that gtk_bin_get_child() does not expose.

But there is a limit as to what we can access. Some inner widgets are tucked away inside a private struct (the issue described here). As such, we have no way to apply a style context to them.

As a result, we can sometimes only apply a background color to some parts of the widget.
In the example below, we styled the Entry and the text of the menu. But the drop down button and the background of the menu cannot be styled.

MenuComboBox_2015.04.07

 

How do other Gtk Developers do it?

You might wonder, with such a limitation, how do other gtk developers get by?
Suppose you’d like to have two combo boxes, a blue and a red one. How would a Gtk Developer implement this?

To find the answer to this mystery I ventured out to the gtk+ irc channel and a guy called ‘Company’ helped me out.
To apply a theme to individual widgets in Gtk3, you would have to give them a unique class ID, then create a provider for the whole screen and select the widget based on it’s unique ID.

I wrote some native Gtk code to try it out and it worked. (In the example I assign an id ‘custom-class-123’ and then theme it from the global theme.

Technically, implementing this in SWT wouldn’t be difficult. But this would be a hack on an a somewhat epic scale. It would mean we would have 1000’s of unique CSS classes to deal with and it’s not yet obvious if it would be possible to remove styling once applied.

The main issue is that SWT’s philosophy is to style each and individual widget, there isn’t really a ‘central’ theming api. Where as Gtk3’s philosophy is to define the CSS only once and be done with it. E.g GtkComboBoxText * { background:red }  and for individual widget styling use CSS classes.

 

So what’s the deal with Check/Radio/Slider icons?

Eclipse has it’s own CSS syntax which differs from GTK. You can’t really take Eclipses’ Dark-theme CSS and just bluntly apply it to Gtk.

For example in Eclipse CSS ‘Label’ and ‘Button’ are defined, but in Gtk CSS this would need to be translated to GtkLabel and (GtkButton|GtkToggleButton|GtkRadioButton|GtkCheckButton [depending on SWT.STYLE bit]).

With that said, Eclipse CSS does not define any icons for GtkCheckButton, GtkRadioButton or sliders. As a result, we get the icons from the underlying GtkTheme if any are defined.

So when the OS has dark icons, Eclipse looks like this: (note the dark check-boxes):

And when the OS has bright icons, Eclipse looks like this:

But if the theme doesn’t define icons, then we draw our own, then it looks like this:

 

Conclusion: So how do we get Eclipse to look nice?

In essence, Eclipse’s theming doesn’t fully live on it’s own. It takes some things from the OS Gtk theme (e.g radio icons, Menu backgrounds in Combo boxes etc).
As such, For best Dark-Eclipse looks on Gtk, you should run Eclipse under a Dark theme like Adwaita-dark and use the ‘dark’ theme from Eclipse’s Appearance settings.

With the latest nightly build, you can make Eclipse look like this:
Eclipse dark looks

Hope it helps.

 

 

Appendix

1** I don’t have a good source that css is not applied recusivley. This is an observation from experimentation. As test, you can run any gtk app, open gtk inspector (Ctrl+shift+d) (if you have gtk3.14), then select a widget, on the 2nd set of tabs select ‘custom CSS’. From GtkComboBoxText you can’t theme the inner GtkToggleButton and GtkEntry from GtkComboBoxText. You can only theme them if you select the inner widgets directly. But the problem is that we don’t have access to those from SWT.
cannot_theme_gtkcomboboxtext_2015.04.07

If you spot an error in any of the text above, or have general feedback, please post a comment, it would be of much help.

9 thoughts on “Eclipse, Dark theme and Gtk. What Eclipse can theme and what needs to be themed by the OS.

  1. With Gnome 3.16 and Adwaita I’m getting pretty good results with the Dark theme and Adwaita dark (via “env GTK_THEME=Adwaita:dark eclipse”).

    There one big problem still: Text selection on “native” inputs (e.g. search box) does select text but gives no visual feedback about the selection at all. Other than that, Mars and Gnome 3.16 seem to be the first time a dark themes actually work quite well on Linux.

    Like

  2. I have a custom tree control that uses standard swt list foreground/background colors (e.g. SWT.COLOR_LIST_BACKGROUND). As these color do change in dark mode, where can i get the ‘new’ colors ?

    Like

    • Hey ya,
      What do you mean by ‘get new colors’?
      The idea is that when you start an application, it is either in bright mode or dark mode. Depending on the mode, SWT.COLOR_LIST_* will return a color that is relevant for that mode.

      Or do you want the color if changing the theme on the fly?

      Like

      • Sorry , my text lost a word: “As these color do NOT change”
        MY experience is that all controls that keep the original/no background are ok – but when i take a color from SWT.COLOR_LIST_*, its still the standard color, not the dark one.

        Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s