diff --git a/src/autocomplete.cc b/src/autocomplete.cc index 50997e7..8d5b684 100644 --- a/src/autocomplete.cc +++ b/src/autocomplete.cc @@ -158,7 +158,7 @@ void Autocomplete::setup_dialog() { auto create_tooltip_buffer = [ this, tooltip = std::move(tooltip) ]() { auto tooltip_buffer = Gtk::TextBuffer::create(view->get_buffer()->get_tag_table()); - tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), tooltip, "def:note"); + tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), tooltip); return tooltip_buffer; }; diff --git a/src/notebook.cc b/src/notebook.cc index 07197f1..f96d8dc 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -41,8 +41,6 @@ Notebook::TabLabel::TabLabel(const boost::filesystem::path &path, std::function< } Notebook::Notebook() : Gtk::Paned(), notebooks(2) { - Gsv::init(); - for(auto ¬ebook: notebooks) { notebook.get_style_context()->add_class("juci_notebook"); notebook.set_scrollable(); diff --git a/src/project.cc b/src/project.cc index d27ecdc..508ffcd 100644 --- a/src/project.cc +++ b/src/project.cc @@ -615,7 +615,7 @@ void Project::LLDB::debug_show_variables() { value.replace(iter, next_char_iter, "?"); } if(view) - tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1), "def:note"); + tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1)); else tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1)); } diff --git a/src/source.cc b/src/source.cc index fd717a9..7235076 100644 --- a/src/source.cc +++ b/src/source.cc @@ -18,26 +18,19 @@ #include #include -// TODO 2019: Remove workarounds when Debian stable and FreeBSD has newer glibmm packages -#if GLIBMM_MAJOR_VERSION>2 || (GLIBMM_MAJOR_VERSION==2 && (GLIBMM_MINOR_VERSION>51 || (GLIBMM_MINOR_VERSION==51 && GLIBMM_MICRO_VERSION>=2))) -using LanguageManager = Gsv::LanguageManager; -using StyleSchemeManager = Gsv::StyleSchemeManager; -#else -class LanguageManager { -public: - static Glib::RefPtr get_default() { - static auto instance = Gsv::LanguageManager::create(); - return instance; - } -}; -class StyleSchemeManager { -public: - static Glib::RefPtr get_default() { - static auto instance = Gsv::StyleSchemeManager::create(); - return instance; - } -}; -#endif +Glib::RefPtr Source::LanguageManager::get_default() { + static auto instance = Gsv::LanguageManager::create(); + return instance; +} +Glib::RefPtr Source::StyleSchemeManager::get_default() { + static auto instance = Gsv::StyleSchemeManager::create(); + static bool first = true; + if(first) { + instance->prepend_search_path((Config::get().home_juci_path/"styles").string()); + first=false; + } + return instance; +} Glib::RefPtr Source::guess_language(const boost::filesystem::path &file_path) { auto language_manager=LanguageManager::get_default(); @@ -143,8 +136,6 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrcreate_tag("def:warning_underline"); get_buffer()->create_tag("def:error"); get_buffer()->create_tag("def:error_underline"); - get_buffer()->create_tag("def:note_background"); - get_buffer()->create_tag("def:note"); auto mark_attr_debug_breakpoint=Gsv::MarkAttributes::create(); Gdk::RGBA rgba; @@ -418,23 +409,10 @@ void Source::View::configure() { SpellCheckView::configure(); DiffView::configure(); - auto style_scheme_manager=StyleSchemeManager::get_default(); - static std::string juci_search_path=(Config::get().home_juci_path/"styles").string(); - bool found_juci_search_path=false; - for(auto &search_path: style_scheme_manager->get_search_path()) { - if(search_path==juci_search_path) { - found_juci_search_path=true; - break; - } - } - if(!found_juci_search_path) - style_scheme_manager->prepend_search_path(juci_search_path); if(Config::get().source.style.size()>0) { - auto scheme = style_scheme_manager->get_scheme(Config::get().source.style); + auto scheme = StyleSchemeManager::get_default()->get_scheme(Config::get().source.style); if(scheme) get_source_buffer()->set_style_scheme(scheme); - else - Terminal::get().print("Error: Could not find gtksourceview style: "+Config::get().source.style+'\n', true); } set_draw_spaces(parse_show_whitespace_characters(Config::get().source.show_whitespace_characters)); @@ -492,17 +470,6 @@ void Source::View::configure() { diagnostic_tag_underline->set_property("underline-rgba", Gdk::RGBA(error_property)); } //TODO: clear tag_class and param_spec? - - //Add tooltip foreground and background - style = scheme->get_style("def:note"); - auto note_tag=get_buffer()->get_tag_table()->lookup("def:note_background"); - if(style->property_background_set()) { - note_tag->property_background()=style->property_background(); - } - note_tag=get_buffer()->get_tag_table()->lookup("def:note"); - if(style->property_foreground_set()) { - note_tag->property_foreground()=style->property_foreground(); - } if(Config::get().menu.keys["source_show_completion"].empty()) { get_completion()->unblock_interactive(); @@ -1198,7 +1165,7 @@ void Source::View::add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk: auto create_tooltip_buffer=[this, spelling=std::move(spelling), error, severity_tag_name]() { auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table()); tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), error ? "Error" : "Warning", severity_tag_name); - tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), ":\n"+spelling, "def:note"); + tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), ":\n"+spelling); return tooltip_buffer; }; diagnostic_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start), get_buffer()->create_mark(end)); diff --git a/src/source.h b/src/source.h index 3053636..9e7b405 100644 --- a/src/source.h +++ b/src/source.h @@ -10,6 +10,17 @@ #include namespace Source { + /// Workaround for buggy Gsv::LanguageManager::get_default() + class LanguageManager { + public: + static Glib::RefPtr get_default(); + }; + /// Workaround for buggy Gsv::StyleSchemeManager::get_default() + class StyleSchemeManager { + public: + static Glib::RefPtr get_default(); + }; + Glib::RefPtr guess_language(const boost::filesystem::path &file_path); class Offset { diff --git a/src/source_clang.cc b/src/source_clang.cc index f258cd0..2faf6ee 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -373,10 +373,10 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) auto end=get_buffer()->get_iter_at_line_index(token_offsets.second.line-1, token_offsets.second.index-1); auto create_tooltip_buffer=[this, &token, &start, &end]() { auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table()); - tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), "Type: "+token.get_cursor().get_type_description(), "def:note"); + tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "Type: "+token.get_cursor().get_type_description()); auto brief_comment=token.get_cursor().get_brief_comments(); if(brief_comment!="") - tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), "\n\n"+brief_comment, "def:note"); + tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+brief_comment); #ifdef JUCI_ENABLE_DEBUG if(Debug::LLDB::get().is_stopped()) { @@ -421,7 +421,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) next_char_iter++; debug_value.replace(iter, next_char_iter, "?"); } - tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), "\n\n"+value_type+": "+debug_value.substr(pos+3, debug_value.size()-(pos+3)-1), "def:note"); + tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+value_type+": "+debug_value.substr(pos+3, debug_value.size()-(pos+3)-1)); } } } diff --git a/src/source_language_protocol.cc b/src/source_language_protocol.cc index 3fe9ee2..a309e18 100644 --- a/src/source_language_protocol.cc +++ b/src/source_language_protocol.cc @@ -963,7 +963,7 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect type_tooltips.clear(); auto create_tooltip_buffer=[this, offset, content=std::move(content)]() { auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table()); - tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), content, "def:note"); + tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), content); #ifdef JUCI_ENABLE_DEBUG if(language_id=="rust" && capabilities.definition) { @@ -991,7 +991,7 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect next_char_iter++; debug_value.replace(iter, next_char_iter, "?"); } - tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), "\n\n"+value_type+": "+debug_value.substr(pos+3, debug_value.size()-(pos+3)-1), "def:note"); + tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), "\n\n"+value_type+": "+debug_value.substr(pos+3, debug_value.size()-(pos+3)-1)); } } } diff --git a/src/tooltips.cc b/src/tooltips.cc index e416cd7..7e61221 100644 --- a/src/tooltips.cc +++ b/src/tooltips.cc @@ -66,23 +66,24 @@ void Tooltip::show(bool disregard_drawn, const std::function &on_motion) if(visual) gtk_widget_set_visual(reinterpret_cast(window->gobj()), visual->gobj()); - auto box=Gtk::manage(new Gtk::Box()); + auto box=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); box->get_style_context()->add_class("juci_tooltip_box"); window->add(*box); text_buffer=create_tooltip_buffer(); wrap_lines(); - auto tooltip_text_view=Gtk::manage(new Gtk::TextView(text_buffer)); + auto tooltip_text_view=Gtk::manage(new Gtk::TextView(text_buffer)); + tooltip_text_view->get_style_context()->add_class("juci_tooltip_text_view"); tooltip_text_view->set_editable(false); - if(text_view) { - auto tag=text_view->get_buffer()->get_tag_table()->lookup("def:note_background"); - box->override_background_color(tag->property_background_rgba()); - tooltip_text_view->override_background_color(tag->property_background_rgba()); - } - else - box->override_background_color(tooltip_text_view->get_style_context()->get_background_color()); + +#if GTK_VERSION_GE(3, 20) box->add(*tooltip_text_view); +#else + auto box2=Gtk::manage(new Gtk::Box()); + box2->pack_start(*tooltip_text_view, true, true, 3); + box->pack_start(*box2, true, true, 3); +#endif auto layout=Pango::Layout::create(tooltip_text_view->get_pango_context()); layout->set_text(text_buffer->get_text()); diff --git a/src/window.cc b/src/window.cc index c97d49b..f547170 100644 --- a/src/window.cc +++ b/src/window.cc @@ -12,6 +12,8 @@ #include "terminal.h" Window::Window() { + Gsv::init(); + set_title("juCi++"); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK|Gdk::LEAVE_NOTIFY_MASK); @@ -135,17 +137,43 @@ Window::Window() { void Window::configure() { Config::get().load(); - auto screen = Gdk::Screen::get_default(); - if(css_provider) - Gtk::StyleContext::remove_provider_for_screen(screen, css_provider); + auto screen = get_screen(); + if(css_provider_theme) + Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_theme); if(Config::get().window.theme_name.empty()) { - css_provider=Gtk::CssProvider::create(); + css_provider_theme=Gtk::CssProvider::create(); Gtk::Settings::get_default()->property_gtk_application_prefer_dark_theme()=(Config::get().window.theme_variant=="dark"); } else - css_provider=Gtk::CssProvider::get_named(Config::get().window.theme_name, Config::get().window.theme_variant); + css_provider_theme=Gtk::CssProvider::get_named(Config::get().window.theme_name, Config::get().window.theme_variant); //TODO: add check if theme exists, or else write error to terminal - Gtk::StyleContext::add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); + Gtk::StyleContext::add_provider_for_screen(screen, css_provider_theme, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); + + auto style_scheme_manager=Source::StyleSchemeManager::get_default(); + if(css_provider_tooltips) + Gtk::StyleContext::remove_provider_for_screen(screen, css_provider_tooltips); + else + css_provider_tooltips=Gtk::CssProvider::create(); + Glib::RefPtr style; + if(Config::get().source.style.size()>0) { + auto scheme = style_scheme_manager->get_scheme(Config::get().source.style); + if(scheme) + style = scheme->get_style("def:note"); + else { + Terminal::get().print("Error: Could not find gtksourceview style: "+Config::get().source.style+'\n', true); + } + } + auto foreground_value = style && style->property_foreground_set() ? style->property_foreground().get_value() : get_style_context()->get_color().to_string(); + auto background_value = style && style->property_background_set() ? style->property_background().get_value() : get_style_context()->get_background_color().to_string(); +#if GTK_VERSION_GE(3, 20) + css_provider_tooltips->load_from_data(".juci_tooltip_box {background-color: "+background_value+";}" + ".juci_tooltip_text_view text {color: "+foreground_value+";background-color: "+background_value+";}"); +#else + css_provider_tooltips->load_from_data(".juci_tooltip_box {background-color: "+background_value+";}" + ".juci_tooltip_text_view *:not(:selected) {color: "+foreground_value+";background-color: "+background_value+";}"); +#endif + get_style_context()->add_provider_for_screen(screen, css_provider_tooltips, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + Menu::get().set_keys(); Terminal::get().configure(); Directories::get().update(); diff --git a/src/window.h b/src/window.h index 24ff4c2..fa9b32d 100644 --- a/src/window.h +++ b/src/window.h @@ -21,7 +21,8 @@ protected: private: Gtk::AboutDialog about; - Glib::RefPtr css_provider; + Glib::RefPtr css_provider_theme; + Glib::RefPtr css_provider_tooltips; void configure(); void set_menu_actions(); diff --git a/tests/source_test.cc b/tests/source_test.cc index c15c5a8..c68581c 100644 --- a/tests/source_test.cc +++ b/tests/source_test.cc @@ -41,6 +41,16 @@ int main() { g_assert(boost::filesystem::remove(source_file)); g_assert(!boost::filesystem::exists(source_file)); + for(int c=0;c<2;++c) { + size_t found=0; + auto style_scheme_manager=Source::StyleSchemeManager::get_default(); + for(auto &search_path: style_scheme_manager->get_search_path()) { + if(search_path=="styles") // found added style + ++found; + } + g_assert(found==1); + } + // replace_text tests { auto buffer=source_view.get_buffer();