Skip to content

Dark Theme

Gerhard Olsson edited this page Dec 31, 2021 · 9 revisions

Background

Theming is difficult to achieve in Git Extensions as there is no general way to override the Windows system colors. Some GUI controls in WinForms are very hard to theme.

Git Extensions from 3.2 uses a dark theme for the UI if a dark theme is used in Windows (this can be setup with WindowsBlinds). This basically adjusts colors that GE can adjust to be reasonable.

Git Extensions 3.4 and 3.5 (but not later) (primarily in https://github.com/gitextensions/gitextensions/pull/7213 as well as #7540) adds theming also if the Windows theme is not dark by overriding WinForms controls by different tricks (and adjusts GE own colors). This can be used to have more than a dark and a light theme, but currently the focus is to make the dark theme supplied with GE good looking.

Git Extensions 4.0 uses .NET 5 and the way theming is applied to 3.5 is no longer possible. It is therefore not possible to change system colors (like form background etc) only application colors (like branch labels in the revision grid) similar to Git Extensions before 3.4. This is tracked in #9191, alternative possibilities are investigated.

This Wiki page lists the current status (and possibly what can be done to address them). It is not intended as a place for questions and answers (see PRs/issues for that). Please edit this page to match the status in the latest development branch related to this. If there are obvious shortcomings when the feature is released, this should be documented in the official documentation.

Console emulation

The console style is set in Detailed/Browse repository window.

Known Issues

All screenshots may not be completely matched to latest version

Other

No theme for popups

This by design, similar to for instance Visual Studio.

image

Bright disabled ComboBox

image

Flashing bright background

Some panels flash brightly at first opening, for instance ConEmu

Scrollbars in Console Emulator is bright

ConEmu cannot be themed currently.

Bright (or system-defined) buttons color after changing DPI

2020-09-29_13-42-03

Restarting Git Extensions should help. Similar effect should be possible after changing Windows theme.

Dark theme compatibility guidelines

Adapting bitmaps

Bitmaps with significant grayscale share may need to be adjusted for dark theme, use AdaptLightness() helper method.

Fix semi-transparent icon borders

Image lists must have ColorDepth = ColorDepth.Depth32Bit otherwise the icons will be rendered with visual artifacts on semi-transparent borders.

new ImageList
{
  ColorDepth = ColorDepth.Depth32Bit
};

Adapting individual colors

Whenever new code uses .NET classes SystemColors, SystemBrushes or SystemPens, it is dark-theme-compatible. Other colors can be dynamically adjusted to dark theme by using AdaptTextColor(), AdaptBackColor(), SetForeColorForBackColor() helper methods.

Implementation details

Overriding winapi calls

To achieve near complete color customization within .NET application, one has to override certain winapi calls in scope of application process, namely some functions from uxtheme.h, also GetSysColor and GetSysColorBrush from winuser.h. The overrides are located in Win32ThemeHooks class. For instance, whenever GetSysColor is called, from managed or unmanaged code, Win32ThemeHooks intercepts the call and returns customized color value from Theme

Overrides related to specific controls or control parts are implemented in ThemeRenderer inheritors, such as ScrollBar renderer

Further tweaking theme overrides

The difficult part in overriding theme-related winapi calls is to figure out the constants CLASS, PART and STATE from MSDN docs on theming which are relevant to your goal.

One great tool to help with this is Theme explorer.

Suppose you want to override how ListView column right border is rendered.

image

because in dark theme it does not look as desired:

image

Run Theme Explorer

image

ListView [Explorer] -> ColumnDetails looks like what we need.

To test our guess, we add to ListViewRenderer.cs, method RenderBackground

case Parts.LVP_COLUMNDETAIL:
  ctx.Graphics.FillRectangle(Brushes.Magenta, prect);
  return Handled;

Run Git Extensions, see what's changed:

image

Luck did not fail us this time! What's left is mechanical work to actually paint the thing the desired way.

Restart required to change theme

Application colors and styles can only be properly adjusted once at startup. Color settings page notifies the user about it when color scheme changes.

Clone this wiki locally