From 30df10cab6d33cbbdcfffc0e43bb43c961adb150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Silva?= Date: Fri, 29 Mar 2019 00:46:53 +0000 Subject: [PATCH] Allow following system theme *and* forcing light / dark theme --- data/de.wolfvollprecht.UberWriter.gschema.xml | 9 ++- data/ui/Preferences.ui | 39 +++++++++--- uberwriter/application.py | 61 ++++++++++++------- uberwriter/theme.py | 5 +- uberwriter/window.py | 8 ++- 5 files changed, 85 insertions(+), 37 deletions(-) diff --git a/data/de.wolfvollprecht.UberWriter.gschema.xml b/data/de.wolfvollprecht.UberWriter.gschema.xml index 82d891c..4d3f7ca 100644 --- a/data/de.wolfvollprecht.UberWriter.gschema.xml +++ b/data/de.wolfvollprecht.UberWriter.gschema.xml @@ -4,9 +4,16 @@ + + true + Set dark mode automatically + + Whether dark mode depends on the system theme, or is set to what the user specifies. + + false - Dark mode + Force dark mode Enable or disable the dark mode. diff --git a/data/ui/Preferences.ui b/data/ui/Preferences.ui index fb995dc..5b34d2b 100644 --- a/data/ui/Preferences.ui +++ b/data/ui/Preferences.ui @@ -37,12 +37,11 @@ 10 10 - + True False end - start - Use dark mode + Set dark mode automatically right @@ -50,6 +49,19 @@ 0 + + + True + False + end + Force dark mode + right + + + 0 + 1 + + True @@ -60,7 +72,7 @@ 0 - 1 + 2 @@ -73,7 +85,18 @@ 0 - 2 + 3 + + + + + True + True + app.dark_mode_auto + + + 1 + 0 @@ -84,7 +107,7 @@ 1 - 0 + 1 @@ -95,7 +118,7 @@ 1 - 1 + 2 @@ -107,7 +130,7 @@ 1 - 2 + 3 diff --git a/uberwriter/application.py b/uberwriter/application.py index 304fed1..b700ef3 100644 --- a/uberwriter/application.py +++ b/uberwriter/application.py @@ -36,6 +36,7 @@ class Application(Gtk.Application): **kwargs) self.window = None self.settings = Settings.new() + self.dark_mode_action = None def do_startup(self, *args, **kwargs): @@ -59,33 +60,35 @@ class Application(Gtk.Application): action.connect("activate", self.on_quit) self.add_action(action) - set_dark_mode = self.settings.get_value("dark-mode") + dark_mode_auto = self.settings.get_value("dark-mode-auto") + action = Gio.SimpleAction.new_stateful("dark_mode_auto", None, + GLib.Variant.new_boolean(dark_mode_auto)) + action.connect("change-state", self.on_dark_mode_auto) + self.add_action(action) + + dark_mode = self.settings.get_value("dark-mode") action = Gio.SimpleAction.new_stateful("dark_mode", None, - GLib.Variant.new_boolean(set_dark_mode)) + GLib.Variant.new_boolean(dark_mode)) action.connect("change-state", self.on_dark_mode) self.add_action(action) - action = Gio.SimpleAction.new_stateful("focus_mode", - None, + action = Gio.SimpleAction.new_stateful("focus_mode", None, GLib.Variant.new_boolean(False)) action.connect("change-state", self.on_focus_mode) self.add_action(action) - action = Gio.SimpleAction.new_stateful("hemingway_mode", - None, + action = Gio.SimpleAction.new_stateful("hemingway_mode", None, GLib.Variant.new_boolean(False)) action.connect("change-state", self.on_hemingway_mode) self.add_action(action) - action = Gio.SimpleAction.new_stateful("fullscreen", - None, + action = Gio.SimpleAction.new_stateful("fullscreen", None, GLib.Variant.new_boolean(False)) action.connect("change-state", self.on_fullscreen) self.add_action(action) - action = Gio.SimpleAction.new_stateful("preview", - None, + action = Gio.SimpleAction.new_stateful("preview", None, GLib.Variant.new_boolean(False)) action.connect("change-state", self.on_preview) self.add_action(action) @@ -94,17 +97,15 @@ class Application(Gtk.Application): action.connect("activate", self.on_search) self.add_action(action) - set_spellcheck = self.settings.get_value("spellcheck") - action = Gio.SimpleAction.new_stateful("spellcheck", - None, - GLib.Variant.new_boolean(set_spellcheck)) + spellcheck = self.settings.get_value("spellcheck") + action = Gio.SimpleAction.new_stateful("spellcheck", None, + GLib.Variant.new_boolean(spellcheck)) action.connect("change-state", self.on_spellcheck) self.add_action(action) - set_gradient_overlay = self.settings.get_value("gradient-overlay") - action = Gio.SimpleAction.new_stateful("draw_gradient", - None, - GLib.Variant.new_boolean(set_gradient_overlay)) + gradient_overlay = self.settings.get_value("gradient-overlay") + action = Gio.SimpleAction.new_stateful("draw_gradient", None, + GLib.Variant.new_boolean(gradient_overlay)) action.connect("change-state", self.on_draw_gradient) self.add_action(action) @@ -163,6 +164,8 @@ class Application(Gtk.Application): self.set_accels_for_action("app.save_as", ["s"]) self.set_accels_for_action("app.quit", ["w", "q"]) + # Theme + self.apply_current_theme() def do_activate(self, *args, **kwargs): @@ -210,8 +213,8 @@ class Application(Gtk.Application): style_provider.load_from_path(theme.gtk_css_path) Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), style_provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION - ) + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) + def on_about(self, _action, _param): builder = get_builder('About') @@ -236,11 +239,25 @@ class Application(Gtk.Application): builder.get_object("shortcuts").set_transient_for(self.window) builder.get_object("shortcuts").show() - def on_dark_mode(self, action, value): + def on_dark_mode_auto(self, action, value, update_dark_mode_auto=True): + action.set_state(value) + self.settings.set_value("dark-mode-auto", GLib.Variant("b", value)) + + if update_dark_mode_auto: + self.on_dark_mode(self.lookup_action("dark_mode"), + GLib.Variant.new_boolean(not value.get_boolean()), + False) + + def on_dark_mode(self, action, value, update_dark_mode_auto=True): action.set_state(value) self.settings.set_value("dark-mode", GLib.Variant("b", value)) - # this changes the headerbar theme accordingly + if update_dark_mode_auto: + self.on_dark_mode_auto(self.lookup_action("dark_mode_auto"), + GLib.Variant.new_boolean(not value.get_boolean()), + False) + + # change the app theme accordingly self.apply_current_theme() # adjust window for theme diff --git a/uberwriter/theme.py b/uberwriter/theme.py index e43ec57..d91d58f 100644 --- a/uberwriter/theme.py +++ b/uberwriter/theme.py @@ -31,11 +31,10 @@ class Theme: @classmethod def get_current(cls): theme_name = Gtk.Settings.get_default().get_property('gtk-theme-name') + dark_mode_auto = cls.settings.get_value('dark-mode-auto').get_boolean() dark_mode = cls.settings.get_value('dark-mode').get_boolean() current_theme = cls.get_for_name(theme_name) - # Technically, we could very easily allow the user to force the light ui on a dark theme. - # However, as there is no inverse of "gtk-application-prefer-dark-theme", we shouldn't do that. - if dark_mode and not current_theme.is_dark and current_theme.inverse_name: + if not dark_mode_auto and dark_mode != current_theme.is_dark and current_theme.inverse_name: current_theme = cls.get_for_name(current_theme.inverse_name, current_theme.name) return current_theme diff --git a/uberwriter/window.py b/uberwriter/window.py index 1ef21be..5927fae 100644 --- a/uberwriter/window.py +++ b/uberwriter/window.py @@ -264,13 +264,15 @@ class Window(Gtk.ApplicationWindow): """Adjusts both the window and the CSD for the current theme. """ + # Update markup buffer's style self.markup_buffer.update_style() - # Reload preview if it exists, otherwise redraw contents of window (self) + # Reload preview if it exists if self.preview_webview: self.show_preview() - else: - self.queue_draw() + + # Redraw contents of window + self.queue_draw() def scrolled(self, widget): """if window scrolled + focusmode make font black again"""