client: Support Dark Mode
Refs #714 Co-authored-by: Niels De Graef <nielsdegraef@gmail.com>
This commit is contained in:
parent
2ef32d2d2d
commit
dbfb7f40da
11 changed files with 196 additions and 57 deletions
|
|
@ -37,6 +37,13 @@
|
|||
<default>true</default>
|
||||
<summary>Display message previews</summary>
|
||||
<description>True if we should display a short preview of each message.</description>
|
||||
</key>
|
||||
|
||||
<key name="unset-html-colors" type="b">
|
||||
<default>false</default>
|
||||
<summary>Unset colors provided in HTML emails</summary>
|
||||
<summary>Override colors in HTML emails</summary>
|
||||
<description>Overrides the original colors in HTML messages to integrate better with the app theme.</description>
|
||||
</key>
|
||||
|
||||
<key name="move-messages-on-tag" type="b">
|
||||
|
|
|
|||
|
|
@ -12,23 +12,18 @@ public class Accounts.SignatureWebView : Components.WebView {
|
|||
|
||||
|
||||
private static WebKit.UserScript? app_script = null;
|
||||
private static WebKit.UserStyleSheet? app_stylesheet = null;
|
||||
|
||||
public static new void load_resources()
|
||||
throws GLib.Error {
|
||||
SignatureWebView.app_script = Components.WebView.load_app_script(
|
||||
"signature-web-view.js"
|
||||
);
|
||||
SignatureWebView.app_stylesheet = Components.WebView.load_app_stylesheet(
|
||||
"signature-web-view.css"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public SignatureWebView(Application.Configuration config) {
|
||||
base(config);
|
||||
this.user_content_manager.add_script(SignatureWebView.app_script);
|
||||
this.user_content_manager.add_style_sheet(SignatureWebView.app_stylesheet);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public class Application.Configuration : Geary.BaseObject {
|
|||
public const string COMPOSE_AS_HTML_KEY = "compose-as-html";
|
||||
public const string CONVERSATION_VIEWER_ZOOM_KEY = "conversation-viewer-zoom";
|
||||
public const string DISPLAY_PREVIEW_KEY = "display-preview";
|
||||
public const string UNSET_HTML_COLORS = "unset-html-colors";
|
||||
public const string FORMATTING_TOOLBAR_VISIBLE = "formatting-toolbar-visible";
|
||||
public const string OPTIONAL_PLUGINS = "optional-plugins";
|
||||
public const string SEARCH_STRATEGY_KEY = "search-strategy";
|
||||
|
|
@ -99,6 +100,10 @@ public class Application.Configuration : Geary.BaseObject {
|
|||
get { return settings.get_boolean(DISPLAY_PREVIEW_KEY); }
|
||||
}
|
||||
|
||||
public bool unset_html_colors {
|
||||
get { return settings.get_boolean(UNSET_HTML_COLORS); }
|
||||
}
|
||||
|
||||
public bool single_key_shortcuts { get; set; default = false; }
|
||||
|
||||
public bool run_in_background {
|
||||
|
|
|
|||
|
|
@ -175,6 +175,17 @@ public class Components.PreferencesWindow : Hdy.PreferencesWindow {
|
|||
trust_images_row.activatable_widget = trust_images;
|
||||
trust_images_row.add(trust_images);
|
||||
|
||||
var unset_html_colors = new Gtk.Switch();
|
||||
unset_html_colors.valign = CENTER;
|
||||
|
||||
var unset_html_colors_row = new Hdy.ActionRow();
|
||||
/// Translators: Preferences label
|
||||
unset_html_colors_row.title = _("_Override the original colors in HTML emails");
|
||||
unset_html_colors_row.subtitle = _("Overrides the original colors in HTML messages to integrate better with the app theme. Requires restart.");
|
||||
unset_html_colors_row.use_underline = true;
|
||||
unset_html_colors_row.activatable_widget = unset_html_colors;
|
||||
unset_html_colors_row.add(unset_html_colors);
|
||||
|
||||
var group = new Hdy.PreferencesGroup();
|
||||
/// Translators: Preferences group title
|
||||
//group.title = _("General");
|
||||
|
|
@ -185,6 +196,7 @@ public class Components.PreferencesWindow : Hdy.PreferencesWindow {
|
|||
group.add(single_key_shortucts_row);
|
||||
group.add(startup_notifications_row);
|
||||
group.add(trust_images_row);
|
||||
group.add(unset_html_colors_row);
|
||||
|
||||
var page = new Hdy.PreferencesPage();
|
||||
/// Translators: Preferences page title
|
||||
|
|
@ -229,6 +241,11 @@ public class Components.PreferencesWindow : Hdy.PreferencesWindow {
|
|||
(GLib.SettingsBindGetMappingShared) settings_trust_images_getter,
|
||||
(GLib.SettingsBindSetMappingShared) settings_trust_images_setter
|
||||
);
|
||||
config.bind(
|
||||
Application.Configuration.UNSET_HTML_COLORS,
|
||||
unset_html_colors,
|
||||
"state"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ public abstract class Components.WebView : WebKit.WebView, Geary.BaseInterface {
|
|||
|
||||
private static WebKit.WebContext? default_context = null;
|
||||
|
||||
private static WebKit.UserStyleSheet? user_stylesheet = null;
|
||||
private static List<WebKit.UserStyleSheet> styles = new List<WebKit.UserStyleSheet>();
|
||||
|
||||
private static WebKit.UserScript? script = null;
|
||||
private static List<WebKit.UserScript> scripts = new List<WebKit.UserScript>();
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -126,14 +126,13 @@ public abstract class Components.WebView : WebKit.WebView, Geary.BaseInterface {
|
|||
*/
|
||||
public static void load_resources(GLib.File user_dir)
|
||||
throws GLib.Error {
|
||||
WebView.script = load_app_script(
|
||||
"components-web-view.js"
|
||||
);
|
||||
WebView.scripts.append(load_app_script("components-web-view.js"));
|
||||
WebView.styles.append(load_app_stylesheet("components-web-view.css"));
|
||||
|
||||
foreach (string name in new string[] { USER_CSS, USER_CSS_LEGACY }) {
|
||||
GLib.File stylesheet = user_dir.get_child(name);
|
||||
try {
|
||||
WebView.user_stylesheet = load_user_stylesheet(stylesheet);
|
||||
WebView.styles.append(load_user_stylesheet(stylesheet));
|
||||
break;
|
||||
} catch (GLib.IOError.NOT_FOUND err) {
|
||||
// All good, try the next one or just exit
|
||||
|
|
@ -350,11 +349,22 @@ public abstract class Components.WebView : WebKit.WebView, Geary.BaseInterface {
|
|||
|
||||
WebKit.UserContentManager content_manager =
|
||||
custom_manager ?? new WebKit.UserContentManager();
|
||||
content_manager.add_script(WebView.script);
|
||||
if (WebView.user_stylesheet != null) {
|
||||
content_manager.add_style_sheet(WebView.user_stylesheet);
|
||||
|
||||
if (config.unset_html_colors) {
|
||||
WebView.scripts.append(
|
||||
new WebKit.UserScript(
|
||||
"window.UNSET_HTML_COLORS = true;",
|
||||
WebKit.UserContentInjectedFrames.TOP_FRAME,
|
||||
WebKit.UserScriptInjectionTime.START,
|
||||
null,
|
||||
null
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
WebView.scripts.foreach(script => content_manager.add_script(script));
|
||||
WebView.styles.foreach(style => content_manager.add_style_sheet(style));
|
||||
|
||||
Object(
|
||||
settings: setts,
|
||||
user_content_manager: content_manager,
|
||||
|
|
|
|||
59
ui/components-web-view.css
Normal file
59
ui/components-web-view.css
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Shared styles for Components.WebView and subclasses.
|
||||
*/
|
||||
|
||||
body {
|
||||
/* Variables */
|
||||
--bg-color: white;
|
||||
--fg-color: black;
|
||||
--quote-container-bg: #e8e8e8;
|
||||
--quote-container-fg: #303030;
|
||||
/* The following was taken from GTK+4 trunk Adwaita theme:
|
||||
* gtk/theme/Adwaita/gtk-contained.css */
|
||||
--button-color: #2e3436;
|
||||
--button-outline-color: rgba(46, 52, 54, 0.3);
|
||||
--button-border-color: #b6b6b3;
|
||||
--button-border-bottom-color: #91918c;
|
||||
--button-background-image: linear-gradient(to bottom, #e8e8e7, #dededd 60%, #cfcfcd);
|
||||
--button-text-shadow-color: rgba(255, 255, 255, 0.76923);
|
||||
--button-box-shadow-color: rgba(255, 255, 255, 0.8);
|
||||
|
||||
--hover-button-color: #2e3436;
|
||||
--hover-button-outline-color: rgba(46, 52, 54, 0.3);
|
||||
--hover-button-border-color: #b6b6b3;
|
||||
--hover-button-border-bottom-color: #91918c;
|
||||
--hover-button-background-image: linear-gradient(to bottom, #f7f7f7, #e8e8e7 60%, #dededd);
|
||||
--hover-button-box-shadow-color: rgba(255, 255, 255, 1);
|
||||
|
||||
/* Adjust default controls and system colors for light and dark mode.
|
||||
See https://www.w3.org/TR/css-color-adjust-1/#color-scheme-effect */
|
||||
color-scheme: light dark;
|
||||
|
||||
color: var(--fg-color);
|
||||
background-color: var(--bg-color);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body[data-geary-theme=dark] {
|
||||
--bg-color: #2a2d30;
|
||||
--fg-color: #eaeaea;
|
||||
--quote-container-bg: #36383b;
|
||||
--quote-container-fg: #e3e3e3;
|
||||
|
||||
/* Adwaita Dark inspired button colors */
|
||||
--button-color: #eeeeec;
|
||||
--button-outline-color: rgba(0, 0, 0, 0.3);
|
||||
--button-border-color: #202020;
|
||||
--button-border-bottom-color: #151515;
|
||||
--button-background-image: linear-gradient(to bottom, #4a4a4a, #3c3c3c 60%, #303030);
|
||||
--button-text-shadow-color: rgba(0, 0, 0, 0.4);
|
||||
--button-box-shadow-color: rgba(0, 0, 0, 0.3);
|
||||
|
||||
--hover-button-color: #ffffff;
|
||||
--hover-button-outline-color: rgba(0, 0, 0, 0.4);
|
||||
--hover-button-border-color: #2c2c2c;
|
||||
--hover-button-border-bottom-color: #1e1e1e;
|
||||
--hover-button-background-image: linear-gradient(to bottom, #5a5a5a, #4c4c4c 60%, #404040);
|
||||
--hover-button-box-shadow-color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
}
|
||||
|
|
@ -71,6 +71,10 @@ PageState.prototype = {
|
|||
// completing.
|
||||
this.updatePreferredHeight();
|
||||
this._contentLoaded();
|
||||
if (window.UNSET_HTML_COLORS) {
|
||||
document.body.setAttribute("data-geary-theme", "dark")
|
||||
unsetHTMLColors(document);
|
||||
}
|
||||
},
|
||||
loadRemoteResources: function() {
|
||||
const TYPES = "*[src], *[srcset]";
|
||||
|
|
@ -182,3 +186,61 @@ let MessageSender = function(name) {
|
|||
_GearyWebExtension.send(name, Array.from(arguments));
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Unsets inline and stylesheet colors from the given document.
|
||||
* @param {Document} doc The HTML document to process.
|
||||
* @returns {void}
|
||||
*/
|
||||
function unsetHTMLColors(doc) {
|
||||
// Slightly modified copy from Evolution
|
||||
// https://gitlab.gnome.org/GNOME/evolution/-/blob/94510bed94e8de641a8d54f2adaec6f02a8972de/data/webkit/e-web-view.js#L1169
|
||||
|
||||
Array.from(doc.styleSheets).forEach(sheet => {
|
||||
|
||||
Array.from(sheet.cssRules).forEach(rule => {
|
||||
|
||||
if (!rule.style || !rule.selectorText )
|
||||
return;
|
||||
|
||||
if (rule.style.color)
|
||||
rule.style.removeProperty("color");
|
||||
|
||||
if (rule.style.backgroundColor)
|
||||
rule.style.removeProperty("background-color");
|
||||
})
|
||||
})
|
||||
|
||||
doc.querySelectorAll("[style],[color],[bgcolor]").forEach(elem => {
|
||||
|
||||
if (["HTML", "IFRAME", "INPUT", "BUTTON", "IMG"].includes(elem.tagName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (elem.style) {
|
||||
if (elem.style.color)
|
||||
elem.style.removeProperty("color");
|
||||
|
||||
if (elem.style.backgroundColor)
|
||||
elem.style.removeProperty("background-color");
|
||||
|
||||
if (elem.style.backgroundImage)
|
||||
elem.style.removeProperty("background-image");
|
||||
|
||||
if (!elem.style.length)
|
||||
elem.removeAttribute("style");
|
||||
}
|
||||
|
||||
elem.removeAttribute("color");
|
||||
elem.removeAttribute("bgcolor");
|
||||
});
|
||||
|
||||
doc.querySelectorAll("body").forEach(elem => {
|
||||
elem.removeAttribute("bgcolor");
|
||||
elem.removeAttribute("text");
|
||||
elem.removeAttribute("link");
|
||||
elem.removeAttribute("alink");
|
||||
elem.removeAttribute("vlink");
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,27 +3,20 @@
|
|||
* Copyright 2017 Michael Gratton <mike@vee.net>
|
||||
*/
|
||||
|
||||
:root {
|
||||
/* Adjust default controls and system colors for light and dark mode.
|
||||
See https://www.w3.org/TR/css-color-adjust-1/#color-scheme-effect */
|
||||
color-scheme: light dark;
|
||||
|
||||
/* Apply canvas background to the root element, so body can darken
|
||||
it using alpha. */
|
||||
background-color: canvas;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: rgb(50% 50% 50% / .05);
|
||||
|
||||
margin: 0 !important;
|
||||
border: 0 !important;
|
||||
padding: 0 !important;
|
||||
font-size: medium !important;
|
||||
}
|
||||
|
||||
body.plain {
|
||||
font-family: monospace;
|
||||
body.plain, body.plain * {
|
||||
font-family: monospace !important;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: medium !important;
|
||||
color: var(--fg-color) !important;
|
||||
background-color: var(--bg-color) !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +43,7 @@ body > div#geary-quote {
|
|||
}
|
||||
|
||||
body > div:focus-within {
|
||||
background-color: canvas;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
body > div#geary-signature:focus-within,
|
||||
|
|
|
|||
|
|
@ -13,11 +13,7 @@
|
|||
transition: height 0.25s !important;
|
||||
}
|
||||
|
||||
:root {
|
||||
/* Adjust default controls and system colors for light and dark mode.
|
||||
See https://www.w3.org/TR/css-color-adjust-1/#color-scheme-effect */
|
||||
color-scheme: light dark;
|
||||
|
||||
html {
|
||||
/* Width must always be defined by the viewport so content doesn't
|
||||
overflow inside the WebView, height must always be defined by the
|
||||
content so the WebView can be sized to fit exactly. */
|
||||
|
|
@ -105,11 +101,11 @@ pre {
|
|||
margin: 0.5em 0;
|
||||
border-radius: 4px;
|
||||
padding: 0.5em 0;
|
||||
color: #303030;
|
||||
background-color: #e8e8e8;/* recv-quoted */
|
||||
color: var(--quote-container-fg);
|
||||
background-color: var(--quote-container-bg);/* recv-quoted */
|
||||
}
|
||||
.geary-sent .geary-quote-container {
|
||||
background-color: #e8e8e8;/* sent-quoted */
|
||||
background-color: var(--quote-container-bg);/* sent-quoted */
|
||||
}
|
||||
|
||||
.geary-quote-container > .geary-quote {
|
||||
|
|
@ -172,24 +168,24 @@ pre {
|
|||
border: 1px solid;
|
||||
border-radius: 3px;
|
||||
transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
color: #2e3436;
|
||||
outline-color: rgba(46, 52, 54, 0.3);
|
||||
border-color: #b6b6b3;
|
||||
border-bottom-color: #91918c;
|
||||
background-image: linear-gradient(to bottom, #e8e8e7, #dededd 60%, #cfcfcd);
|
||||
text-shadow: 0 1px rgba(255, 255, 255, 0.76923);
|
||||
box-shadow: inset 0 1px rgba(255, 255, 255, 0.8);
|
||||
color: var(--button-color);
|
||||
outline-color: var(--button-outline-color);
|
||||
border-color: var(--button-border-color);
|
||||
border-bottom-color: var(--button-border-bottom-color);
|
||||
background-image: var(--button-background-image);
|
||||
text-shadow: 0 1px var(--button-text-shadow-color);
|
||||
box-shadow: inset 0 1px var(--button-box-shadow-color);
|
||||
}
|
||||
.geary-quote-container .geary-button:hover {
|
||||
/* Likewise the properties below also workaround WK Bug 166648,
|
||||
* and taken from gtk/theme/Adwaita/gtk-contained.css. */
|
||||
color: #2e3436;
|
||||
outline-color: rgba(46, 52, 54, 0.3);
|
||||
border-color: #b6b6b3;
|
||||
border-bottom-color: #91918c;
|
||||
text-shadow: 0 1px rgba(255, 255, 255, 0.76923);
|
||||
box-shadow: inset 0 1px white;
|
||||
background-image: linear-gradient(to bottom, #f7f7f7, #e8e8e7 60%, #dededd);
|
||||
color: var(--hover-button-color);
|
||||
outline-color: var(--hover-button-outline-color);
|
||||
border-color: var(--hover-button-border-color);
|
||||
border-bottom-color: var(--hover-button-border-bottom-color);
|
||||
text-shadow: 0 1px var(--button-text-shadow-color);
|
||||
box-shadow: inset 0 1px var(--hover-button-box-shadow-color);
|
||||
background-image: var(--hover-button-background-image);
|
||||
}
|
||||
|
||||
/* Highlight search terms */
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
<file compressed="true" preprocess="xml-stripblanks">application-main-window.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">certificate_warning_dialog.glade</file>
|
||||
<file compressed="true">components-web-view.js</file>
|
||||
<file compressed="true">components-web-view.css</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">components-attachment-pane.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">components-attachment-pane-menus.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">components-attachment-view.ui</file>
|
||||
|
|
@ -49,7 +50,6 @@
|
|||
<file compressed="true" preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">password-dialog.glade</file>
|
||||
<file compressed="true" preprocess="xml-stripblanks">problem-details-dialog.ui</file>
|
||||
<file compressed="true">signature-web-view.css</file>
|
||||
<file compressed="true">signature-web-view.js</file>
|
||||
<file compressed="true">geary.css</file>
|
||||
<file compressed="true">single-key-shortcuts.css</file>
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
:root {
|
||||
/* Adjust default controls and system colors for light and dark mode.
|
||||
See https://www.w3.org/TR/css-color-adjust-1/#color-scheme-effect */
|
||||
color-scheme: light dark;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue