diff options
author | HebaruSan <HebaruSan@users.noreply.github.com> | 2019-11-27 21:13:11 +0300 |
---|---|---|
committer | Alexander Köplinger <alex.koeplinger@outlook.com> | 2019-11-27 21:13:11 +0300 |
commit | d62eed676e0ec3e694d4a70caf75128be035a5d3 (patch) | |
tree | dfb0a14890d7ad570972c183a6fcaca51e8905d9 /mcs/class/System.Windows.Forms | |
parent | a73e7b8af24823bedcef424844b501b609e0dd37 (diff) |
[WinForms] Fix X11 theming (#17888)
## Background
In Mono 5 and earlier, the active GTK or KDE theme would be sourced for system colors, allowing dark themes to be obeyed:
![image](https://user-images.githubusercontent.com/1559108/69486043-f3bf0500-0e0c-11ea-9b29-1654ba4e6d9a.png)
This allowed WinForms apps to blend in and look more like native apps.
## Problem
In Mono 6, this capability was lost (as noted in passing in #14325). WinForms apps now only look like this, regardless of the system color settings:
![image](https://user-images.githubusercontent.com/1559108/69486114-dccce280-0e0d-11ea-8107-fe1653b2d816.png)
This looks somewhat jarring and worse than previous Mono releases, for users with a dark system theme.
## Cause
During load of the system settings (in the static constructor of `X11DesktopColors`), `Theme.SetSystemColors` passes system color data to `System.Drawing.KnownColors.Update`, which populates them into `System.Drawing.KnownColors.ArgbValues`. In Mono 5 and earlier, this flowed through to the visible UI.
It seems that as of Mono 6, this table no longer affects the visible WinForms UI (although it is still being updated!). Instead, a same-but-different table in `System.Drawing.KnownColorTable` drives the system colors now. I was not able to identify the commit in which this change was made.
## Changes
Now `Theme.SetSystemColors` accesses `System.Drawing.KnownColorTable.s_colorTable` instead, and WinForms apps once again obey GTK and KDE themes:
![image](https://user-images.githubusercontent.com/1559108/69486043-f3bf0500-0e0c-11ea-9b29-1654ba4e6d9a.png)
Fixes KSP-CKAN/CKAN#2881.
Diffstat (limited to 'mcs/class/System.Windows.Forms')
-rw-r--r-- | mcs/class/System.Windows.Forms/System.Windows.Forms/Theme.cs | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/Theme.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/Theme.cs index b4294792db9..caef2e88e81 100644 --- a/mcs/class/System.Windows.Forms/System.Windows.Forms/Theme.cs +++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/Theme.cs @@ -191,7 +191,7 @@ namespace System.Windows.Forms protected Color defaultWindowBackColor; protected Color defaultWindowForeColor; internal SystemResPool ResPool = new SystemResPool (); - private MethodInfo update; + private int[] knownColorTable; protected Theme () { @@ -199,13 +199,23 @@ namespace System.Windows.Forms private void SetSystemColors (KnownColor kc, Color value) { - if (update == null) { - Type known_colors = Type.GetType ("System.Drawing.KnownColors, " + Consts.AssemblySystem_Drawing); - if (known_colors != null) - update = known_colors.GetMethod ("Update", BindingFlags.Static | BindingFlags.Public); + if (knownColorTable == null) { + Type knownColorTableClass = Type.GetType ("System.Drawing.KnownColorTable, " + Consts.AssemblySystem_Drawing); + if (knownColorTableClass != null) + { + MethodInfo ensureMethod = knownColorTableClass.GetMethod ("EnsureColorTable", BindingFlags.Static | BindingFlags.NonPublic); + if (ensureMethod != null) { + ensureMethod.Invoke(null, new object[]{}); + FieldInfo colorTableField = knownColorTableClass.GetField ("s_colorTable", BindingFlags.Static | BindingFlags.NonPublic); + if (colorTableField != null) { + knownColorTable = colorTableField.GetValue (null) as int[]; + } + } + } + } + if (knownColorTable != null) { + knownColorTable[(int)kc] = value.ToArgb(); } - if (update != null) - update.Invoke (null, new object [2] { (int)kc, value.ToArgb () }); } /* OS Feature support */ |