Allow following system theme *and* forcing light / dark theme

ft.font-size^2
Gonçalo Silva 2019-03-29 00:46:53 +00:00
parent 7a9b878d02
commit 30df10cab6
5 changed files with 85 additions and 37 deletions

View File

@ -4,9 +4,16 @@
<schema path="/de/wolfvollprecht/UberWriter/" id="de.wolfvollprecht.UberWriter"> <schema path="/de/wolfvollprecht/UberWriter/" id="de.wolfvollprecht.UberWriter">
<key name='dark-mode-auto' type='b'>
<default>true</default>
<summary>Set dark mode automatically</summary>
<description>
Whether dark mode depends on the system theme, or is set to what the user specifies.
</description>
</key>
<key name='dark-mode' type='b'> <key name='dark-mode' type='b'>
<default>false</default> <default>false</default>
<summary>Dark mode</summary> <summary>Force dark mode</summary>
<description> <description>
Enable or disable the dark mode. Enable or disable the dark mode.
</description> </description>

View File

@ -37,12 +37,11 @@
<property name="row_spacing">10</property> <property name="row_spacing">10</property>
<property name="column_spacing">10</property> <property name="column_spacing">10</property>
<child> <child>
<object class="GtkLabel" id="Dark_mode_label"> <object class="GtkLabel" id="Dark_mode_auto_label">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="halign">end</property> <property name="halign">end</property>
<property name="valign">start</property> <property name="label" translatable="yes">Set dark mode automatically</property>
<property name="label" translatable="yes">Use dark mode</property>
<property name="justify">right</property> <property name="justify">right</property>
</object> </object>
<packing> <packing>
@ -50,6 +49,19 @@
<property name="top_attach">0</property> <property name="top_attach">0</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkLabel" id="Dark_mode_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Force dark mode</property>
<property name="justify">right</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child> <child>
<object class="GtkLabel" id="Spellcheck_label"> <object class="GtkLabel" id="Spellcheck_label">
<property name="visible">True</property> <property name="visible">True</property>
@ -60,7 +72,7 @@
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">1</property> <property name="top_attach">2</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -73,7 +85,18 @@
</object> </object>
<packing> <packing>
<property name="left_attach">0</property> <property name="left_attach">0</property>
<property name="top_attach">2</property> <property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="Dark_mode_auto_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="action_name">app.dark_mode_auto</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -84,7 +107,7 @@
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">0</property> <property name="top_attach">1</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -95,7 +118,7 @@
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">1</property> <property name="top_attach">2</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -107,7 +130,7 @@
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="top_attach">2</property> <property name="top_attach">3</property>
</packing> </packing>
</child> </child>
</object> </object>

View File

@ -36,6 +36,7 @@ class Application(Gtk.Application):
**kwargs) **kwargs)
self.window = None self.window = None
self.settings = Settings.new() self.settings = Settings.new()
self.dark_mode_action = None
def do_startup(self, *args, **kwargs): def do_startup(self, *args, **kwargs):
@ -59,33 +60,35 @@ class Application(Gtk.Application):
action.connect("activate", self.on_quit) action.connect("activate", self.on_quit)
self.add_action(action) 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", action = Gio.SimpleAction.new_stateful("dark_mode",
None, None,
GLib.Variant.new_boolean(set_dark_mode)) GLib.Variant.new_boolean(dark_mode))
action.connect("change-state", self.on_dark_mode) action.connect("change-state", self.on_dark_mode)
self.add_action(action) self.add_action(action)
action = Gio.SimpleAction.new_stateful("focus_mode", action = Gio.SimpleAction.new_stateful("focus_mode", None,
None,
GLib.Variant.new_boolean(False)) GLib.Variant.new_boolean(False))
action.connect("change-state", self.on_focus_mode) action.connect("change-state", self.on_focus_mode)
self.add_action(action) self.add_action(action)
action = Gio.SimpleAction.new_stateful("hemingway_mode", action = Gio.SimpleAction.new_stateful("hemingway_mode", None,
None,
GLib.Variant.new_boolean(False)) GLib.Variant.new_boolean(False))
action.connect("change-state", self.on_hemingway_mode) action.connect("change-state", self.on_hemingway_mode)
self.add_action(action) self.add_action(action)
action = Gio.SimpleAction.new_stateful("fullscreen", action = Gio.SimpleAction.new_stateful("fullscreen", None,
None,
GLib.Variant.new_boolean(False)) GLib.Variant.new_boolean(False))
action.connect("change-state", self.on_fullscreen) action.connect("change-state", self.on_fullscreen)
self.add_action(action) self.add_action(action)
action = Gio.SimpleAction.new_stateful("preview", action = Gio.SimpleAction.new_stateful("preview", None,
None,
GLib.Variant.new_boolean(False)) GLib.Variant.new_boolean(False))
action.connect("change-state", self.on_preview) action.connect("change-state", self.on_preview)
self.add_action(action) self.add_action(action)
@ -94,17 +97,15 @@ class Application(Gtk.Application):
action.connect("activate", self.on_search) action.connect("activate", self.on_search)
self.add_action(action) self.add_action(action)
set_spellcheck = self.settings.get_value("spellcheck") spellcheck = self.settings.get_value("spellcheck")
action = Gio.SimpleAction.new_stateful("spellcheck", action = Gio.SimpleAction.new_stateful("spellcheck", None,
None, GLib.Variant.new_boolean(spellcheck))
GLib.Variant.new_boolean(set_spellcheck))
action.connect("change-state", self.on_spellcheck) action.connect("change-state", self.on_spellcheck)
self.add_action(action) self.add_action(action)
set_gradient_overlay = self.settings.get_value("gradient-overlay") gradient_overlay = self.settings.get_value("gradient-overlay")
action = Gio.SimpleAction.new_stateful("draw_gradient", action = Gio.SimpleAction.new_stateful("draw_gradient", None,
None, GLib.Variant.new_boolean(gradient_overlay))
GLib.Variant.new_boolean(set_gradient_overlay))
action.connect("change-state", self.on_draw_gradient) action.connect("change-state", self.on_draw_gradient)
self.add_action(action) self.add_action(action)
@ -163,6 +164,8 @@ class Application(Gtk.Application):
self.set_accels_for_action("app.save_as", ["<Ctl><shift>s"]) self.set_accels_for_action("app.save_as", ["<Ctl><shift>s"])
self.set_accels_for_action("app.quit", ["<Ctl>w", "<Ctl>q"]) self.set_accels_for_action("app.quit", ["<Ctl>w", "<Ctl>q"])
# Theme
self.apply_current_theme() self.apply_current_theme()
def do_activate(self, *args, **kwargs): def do_activate(self, *args, **kwargs):
@ -210,8 +213,8 @@ class Application(Gtk.Application):
style_provider.load_from_path(theme.gtk_css_path) style_provider.load_from_path(theme.gtk_css_path)
Gtk.StyleContext.add_provider_for_screen( Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(), style_provider, Gdk.Screen.get_default(), style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
)
def on_about(self, _action, _param): def on_about(self, _action, _param):
builder = get_builder('About') 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").set_transient_for(self.window)
builder.get_object("shortcuts").show() 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) action.set_state(value)
self.settings.set_value("dark-mode", GLib.Variant("b", 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() self.apply_current_theme()
# adjust window for theme # adjust window for theme

View File

@ -31,11 +31,10 @@ class Theme:
@classmethod @classmethod
def get_current(cls): def get_current(cls):
theme_name = Gtk.Settings.get_default().get_property('gtk-theme-name') 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() dark_mode = cls.settings.get_value('dark-mode').get_boolean()
current_theme = cls.get_for_name(theme_name) 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. if not dark_mode_auto and dark_mode != current_theme.is_dark and current_theme.inverse_name:
# 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:
current_theme = cls.get_for_name(current_theme.inverse_name, current_theme.name) current_theme = cls.get_for_name(current_theme.inverse_name, current_theme.name)
return current_theme return current_theme

View File

@ -264,13 +264,15 @@ class Window(Gtk.ApplicationWindow):
"""Adjusts both the window and the CSD for the current theme. """Adjusts both the window and the CSD for the current theme.
""" """
# Update markup buffer's style
self.markup_buffer.update_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: if self.preview_webview:
self.show_preview() self.show_preview()
else:
self.queue_draw() # Redraw contents of window
self.queue_draw()
def scrolled(self, widget): def scrolled(self, widget):
"""if window scrolled + focusmode make font black again""" """if window scrolled + focusmode make font black again"""