forked from Mirrors/apostrophe
Allow following system theme *and* forcing light / dark theme
parent
7a9b878d02
commit
30df10cab6
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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"""
|
||||||
|
|
Loading…
Reference in New Issue