diff --git a/data/io.elementary.code.gschema.xml b/data/io.elementary.code.gschema.xml index 6ec10220c8..5236ea1c64 100644 --- a/data/io.elementary.code.gschema.xml +++ b/data/io.elementary.code.gschema.xml @@ -135,6 +135,11 @@ Request dark Gtk stylesheet variant Switches between dark and light style + + false + Use the Gtk stylesheet variant set by the system + Follow the system setting for dark or light Gtk style + false Whether search is cyclic diff --git a/src/MainWindow.vala b/src/MainWindow.vala index fef536c599..4104647c6e 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -228,9 +228,6 @@ namespace Scratch { default_width = rect.width; default_height = rect.height; - var gtk_settings = Gtk.Settings.get_default (); - gtk_settings.gtk_application_prefer_dark_theme = Scratch.settings.get_boolean ("prefer-dark-style"); - clipboard = Gtk.Clipboard.get_for_display (get_display (), Gdk.SELECTION_CLIPBOARD); plugins = new Scratch.Services.PluginsManager (this, app.app_cmd_name.down ()); @@ -240,6 +237,10 @@ namespace Scratch { // Set up layout init_layout (); + set_color_scheme (); + Granite.Settings.get_default ().notify["prefers-color-scheme"].connect (set_color_scheme); + Scratch.settings.changed["follow-system-style"].connect (set_color_scheme); + var window_state = Scratch.saved_state.get_enum ("window-state"); switch (window_state) { case ScratchWindowState.MAXIMIZED: @@ -450,6 +451,21 @@ namespace Scratch { set_widgets_sensitive (false); } + private void set_color_scheme () { + var gtk_settings = Gtk.Settings.get_default (); + var granite_settings = Granite.Settings.get_default (); + + if (Scratch.settings.get_boolean ("follow-system-style")) { + gtk_settings.gtk_application_prefer_dark_theme = + granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK; + Scratch.settings.changed ("style-scheme"); + } else { + + gtk_settings.gtk_application_prefer_dark_theme = Scratch.settings.get_boolean ("prefer-dark-style"); + toolbar.activate_color_button (); + } + } + private void open_binary (File file) { if (!file.query_exists ()) { return; diff --git a/src/Widgets/DocumentView.vala b/src/Widgets/DocumentView.vala index e0299bdfb5..335a4c8919 100644 --- a/src/Widgets/DocumentView.vala +++ b/src/Widgets/DocumentView.vala @@ -98,7 +98,11 @@ public class Scratch.Widgets.DocumentView : Granite.Widgets.DynamicNotebook { ); update_inline_tab_colors (); - Scratch.settings.changed["style-scheme"].connect (update_inline_tab_colors); + Scratch.settings.changed.connect ((key) => { + if (key == "style-scheme" || key == "follow-system-style") { + update_inline_tab_colors (); + } + }); // Handle Drag-and-drop of files onto add-tab button to create document Gtk.TargetEntry uris = {"text/uri-list", 0, TargetType.URI_LIST}; @@ -107,25 +111,23 @@ public class Scratch.Widgets.DocumentView : Granite.Widgets.DynamicNotebook { } private void update_inline_tab_colors () { - var sssm = Gtk.SourceStyleSchemeManager.get_default (); - var style_scheme = Scratch.settings.get_string ("style-scheme"); - if (style_scheme in sssm.scheme_ids) { - var theme = sssm.get_scheme (style_scheme); - var text_color_data = theme.get_style ("text"); - - // Default gtksourceview background color is white - var color = "#FFFFFF"; - if (text_color_data != null) { - // If the current style has a background color, use that - color = text_color_data.background; - } + var theme = SourceView.get_style_scheme_from_settings (); + var text_color_data = theme.get_style ("text"); + + // Default gtksourceview background color is white + var color = "#FFFFFF"; + if (text_color_data != null) { + // If the current style has a background color, use that + color = text_color_data.background; + } else { + warning ("No text color in scheme"); + } - var define = "@define-color tab_base_color %s;".printf (color); - try { - style_provider.load_from_data (define); - } catch (Error e) { - critical ("Unable to set inline tab styling, going back to classic notebook tabs"); - } + var define = "@define-color tab_base_color %s;".printf (color); + try { + style_provider.load_from_data (define); + } catch (Error e) { + critical ("Unable to set inline tab styling, going back to classic notebook tabs"); } } diff --git a/src/Widgets/HeaderBar.vala b/src/Widgets/HeaderBar.vala index 2ca4efef59..ee190bd248 100644 --- a/src/Widgets/HeaderBar.vala +++ b/src/Widgets/HeaderBar.vala @@ -20,6 +20,9 @@ */ namespace Scratch.Widgets { + public const string STYLE_SCHEME_HIGH_CONTRAST = "classic"; + public const string STYLE_SCHEME_LIGHT = "solarized-light"; + public const string STYLE_SCHEME_DARK = "solarized-dark"; public class HeaderBar : Hdy.HeaderBar { public Gtk.Menu share_menu; public Gtk.MenuButton share_app_menu; @@ -30,9 +33,11 @@ namespace Scratch.Widgets { public Code.ChooseProjectButton choose_project_button; public Gtk.Revealer choose_project_revealer; - private const string STYLE_SCHEME_HIGH_CONTRAST = "classic"; - private const string STYLE_SCHEME_LIGHT = "solarized-light"; - private const string STYLE_SCHEME_DARK = "solarized-dark"; + private Gtk.RadioButton color_button_none; + private Gtk.RadioButton color_button_white; + private Gtk.RadioButton color_button_light; + private Gtk.RadioButton color_button_dark; + public HeaderBar () { Object ( @@ -129,21 +134,56 @@ namespace Scratch.Widgets { font_size_grid.add (zoom_default_button); font_size_grid.add (zoom_in_button); + var follow_system_label = new Gtk.Label (_("Follow System Style")) { + halign = Gtk.Align.START, + hexpand = true, + vexpand = false + }; + + var follow_system_switch = new Gtk.Switch () { + valign = Gtk.Align.START + }; + + var follow_system_grid = new Gtk.Grid () { + column_spacing = 12 + }; + follow_system_grid.add (follow_system_label); + follow_system_grid.add (follow_system_switch); + + var follow_system_button = new Gtk.ModelButton (); + follow_system_button.get_child ().destroy (); + follow_system_button.add (follow_system_grid); + // Intentionally never attached so we can have a non-selected state - var color_button_none = new Gtk.RadioButton (null); + color_button_none = new Gtk.RadioButton (null); - var color_button_white = new Gtk.RadioButton.from_widget (color_button_none); + color_button_white = new Gtk.RadioButton.from_widget (color_button_none); color_button_white.halign = Gtk.Align.CENTER; style_color_button (color_button_white, STYLE_SCHEME_HIGH_CONTRAST); - var color_button_light = new Gtk.RadioButton.from_widget (color_button_none); + color_button_light = new Gtk.RadioButton.from_widget (color_button_none); color_button_light.halign = Gtk.Align.CENTER; style_color_button (color_button_light, STYLE_SCHEME_LIGHT); - var color_button_dark = new Gtk.RadioButton.from_widget (color_button_none); + color_button_dark = new Gtk.RadioButton.from_widget (color_button_none); color_button_dark.halign = Gtk.Align.CENTER; style_color_button (color_button_dark, STYLE_SCHEME_DARK); + var color_grid = new Gtk.Grid () { + column_homogeneous = true, + margin_start = 12, + margin_end = 12, + margin_top = 6, + margin_bottom = 6 + }; + + color_grid.add (color_button_white); + color_grid.add (color_button_light); + color_grid.add (color_button_dark); + + var color_revealer = new Gtk.Revealer (); + color_revealer.add (color_grid); + var menu_separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL); menu_separator.margin_top = 12; @@ -166,12 +206,11 @@ namespace Scratch.Widgets { menu_grid.orientation = Gtk.Orientation.VERTICAL; menu_grid.width_request = 200; menu_grid.attach (font_size_grid, 0, 0, 3, 1); - menu_grid.attach (color_button_white, 0, 1, 1, 1); - menu_grid.attach (color_button_light, 1, 1, 1, 1); - menu_grid.attach (color_button_dark, 2, 1, 1, 1); - menu_grid.attach (menu_separator, 0, 2, 3, 1); - menu_grid.attach (toggle_sidebar_menuitem, 0, 3, 3, 1); - menu_grid.attach (preferences_menuitem, 0, 6, 3); + menu_grid.attach (follow_system_button, 0, 1, 3, 1); + menu_grid.attach (color_revealer, 0, 2, 3, 1); + menu_grid.attach (menu_separator, 0, 3, 3, 1); + menu_grid.attach (toggle_sidebar_menuitem, 0, 4, 3, 1); + menu_grid.attach (preferences_menuitem, 0, 5, 3, 1); menu_grid.show_all (); var menu = new Gtk.Popover (null); @@ -217,21 +256,26 @@ namespace Scratch.Widgets { } }); - var gtk_settings = Gtk.Settings.get_default (); + Scratch.settings.bind ( + "follow-system-style", + follow_system_switch, + "active", + SettingsBindFlags.DEFAULT + ); - switch (Scratch.settings.get_string ("style-scheme")) { - case STYLE_SCHEME_HIGH_CONTRAST: - color_button_white.active = true; - break; - case STYLE_SCHEME_LIGHT: - color_button_light.active = true; - break; - case STYLE_SCHEME_DARK: - color_button_dark.active = true; - break; - default: - color_button_none.active = true; - } + follow_system_button.button_release_event.connect (() => { + follow_system_switch.activate (); + return Gdk.EVENT_STOP; + }); + + follow_system_switch.bind_property ( + "active", + color_revealer, + "reveal-child", + GLib.BindingFlags.SYNC_CREATE | BindingFlags.INVERT_BOOLEAN + ); + + var gtk_settings = Gtk.Settings.get_default (); color_button_dark.clicked.connect (() => { Scratch.settings.set_boolean ("prefer-dark-style", true); @@ -252,6 +296,23 @@ namespace Scratch.Widgets { }); } + public void activate_color_button () { + switch (Scratch.settings.get_string ("style-scheme")) { + case STYLE_SCHEME_HIGH_CONTRAST: + color_button_white.active = true; + break; + case STYLE_SCHEME_LIGHT: + color_button_light.active = true; + break; + case STYLE_SCHEME_DARK: + color_button_dark.active = true; + break; + default: + color_button_none.active = true; + break; + } + } + private void style_color_button (Gtk.Widget color_button, string style_id) { string background = "#FFF"; string foreground = "#333"; diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index d14724d371..75a45ff186 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -22,7 +22,6 @@ namespace Scratch.Widgets { public class SourceView : Gtk.SourceView { public Gtk.SourceLanguageManager manager; - public Gtk.SourceStyleSchemeManager style_scheme_manager; public Gtk.CssProvider font_css_provider; public Gtk.TextTag warning_tag; public Gtk.TextTag error_tag; @@ -87,7 +86,6 @@ namespace Scratch.Widgets { expand = true; manager = Gtk.SourceLanguageManager.get_default (); - style_scheme_manager = new Gtk.SourceStyleSchemeManager (); font_css_provider = new Gtk.CssProvider (); get_style_context ().add_provider (font_css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); @@ -115,8 +113,6 @@ namespace Scratch.Widgets { source_buffer.tag_table.add (error_tag); source_buffer.tag_table.add (warning_tag); - restore_settings (); - Gtk.drag_dest_add_uri_targets (this); restore_settings (); @@ -292,12 +288,25 @@ namespace Scratch.Widgets { critical (e.message); } - var scheme = style_scheme_manager.get_scheme (Scratch.settings.get_string ("style-scheme")); - source_buffer.style_scheme = scheme ?? style_scheme_manager.get_scheme ("classic"); + source_buffer.style_scheme = SourceView.get_style_scheme_from_settings (); git_diff_gutter_renderer.set_style_scheme (source_buffer.style_scheme); style_changed (source_buffer.style_scheme); } + public static Gtk.SourceStyleScheme get_style_scheme_from_settings () { + var sssm = Gtk.SourceStyleSchemeManager.get_default (); + string style_scheme = STYLE_SCHEME_LIGHT; + if (Scratch.settings.get_boolean ("follow-system-style")) { + if (Granite.Settings.get_default ().prefers_color_scheme == Granite.Settings.ColorScheme.DARK) { + style_scheme = STYLE_SCHEME_DARK; + } + } else { + style_scheme = Scratch.settings.get_string ("style-scheme"); + } + + return sssm.get_scheme (style_scheme) ?? sssm.get_scheme ("classic"); + } + private void update_settings () { var source_buffer = (Gtk.SourceBuffer) buffer; Scratch.settings.set_boolean ("show-right-margin", show_right_margin);