roundabout,
created on Sunday, 29 June 2025, 20:25:11 (1751228711),
received on Sunday, 29 June 2025, 20:25:14 (1751228714)
Author identity: vlad <vlad.muntoiu@gmail.com>
9417fde57a0253b3f6cf4d9fdf55e6160cab0984
gpanthera.cc
@@ -547,7 +547,6 @@ namespace gPanthera {
auto new_notebook = Gtk::make_managed<ContentNotebook>(new_stack, new_switcher, this_notebook ? this_notebook->get_tab_position() : Gtk::PositionType::TOP); new_stack->add_page(*page); new_stack->set_visible_child(*page); content_manager->set_last_operated_page(page);if(x < width / 4) { this->make_paned(Gtk::Orientation::HORIZONTAL, Gtk::PackType::START); if(auto paned = dynamic_cast<Gtk::Paned*>(this->get_parent()->get_parent())) {
@@ -569,6 +568,7 @@ namespace gPanthera {
paned->set_end_child(*new_notebook); } } content_manager->set_last_operated_page(page);} return true; // Drop OK
@@ -1008,6 +1008,7 @@ namespace gPanthera {
void ContentPage::redock(ContentStack *stack) { if(stack == nullptr) { content_manager->signal_page_moving.emit(this);if(this->stack) { this->stack->remove(*this); if(dynamic_cast<ContentNotebook*>(this->stack->get_parent()) && !this->stack->get_first_child()) {
@@ -1028,6 +1029,7 @@ namespace gPanthera {
if(this->stack == stack) { return; } content_manager->signal_page_moving.emit(this);if(this->stack != nullptr) { if(dynamic_cast<ContentNotebook*>(this->stack->get_parent()) && (!this->stack->get_first_child() || (this->stack->get_first_child() == this && !this->stack->get_first_child()->get_next_sibling()))) { this->stack->remove(*this);
@@ -1045,6 +1047,7 @@ namespace gPanthera {
old_stack->signal_leave_empty.emit(); } } content_manager->signal_page_moved.emit(this);} ContentPage::ContentPage(std::shared_ptr<ContentManager> content_manager, ContentStack *stack, Gtk::Widget *child, Gtk::Widget *tab_widget) :
gpanthera.hh
@@ -127,7 +127,7 @@ namespace gPanthera {
public: ContentPage *get_last_operated_page() const; void set_last_operated_page(ContentPage *page); sigc::signal<void(ContentPage*)> signal_page_operated;sigc::signal<void(ContentPage*)> signal_page_operated, signal_page_moving, signal_page_moved;std::vector<ContentStack*> stacks; ContentManager();
panthera-www.cc
@@ -315,8 +315,30 @@ private:
HistoryViewer *history_viewer; gPanthera::ContentPage *controlled_page = nullptr; gPanthera::ContentStack *controlled_stack = nullptr; Glib::RefPtr<Gio::SimpleAction> back_action, forward_action, reload_action; Gtk::Button *go_button; void enable_controls() { back_action->set_enabled(true); forward_action->set_enabled(true); reload_action->set_enabled(true); url_bar->set_sensitive(true); go_button->set_sensitive(true); } void disable_controls() { back_action->set_enabled(false); forward_action->set_enabled(false); reload_action->set_enabled(false); url_bar->set_sensitive(false); url_bar->set_text(""); go_button->set_sensitive(false); } sigc::connection moving_connection, moved_connection;public: friend class PantheraWww; explicit PantheraWindow(Gtk::Application *application) : Gtk::ApplicationWindow() { // There is a constructor with Glib::RefPtr<Gtk::Application>, but it is not appropriate // because the window will own the application, creating a cycle
@@ -361,9 +383,9 @@ public:
outer_paned->set_start_child(*dock_stack_2); auto inner_paned = Gtk::make_managed<Gtk::Paned>(Gtk::Orientation::VERTICAL); auto content = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 0); panthera->content_manager = std::make_shared<gPanthera::ContentManager>();std::function<bool(gPanthera::ContentPage*)> detach_handler; detach_handler = [](gPanthera::ContentPage *widget) {detach_handler = [this](gPanthera::ContentPage *widget) {auto new_stack = Gtk::make_managed<gPanthera::ContentStack>(widget->content_manager, widget->get_stack()->get_detach_handler()); auto new_switcher = Gtk::make_managed<gPanthera::ContentTabBar>(new_stack, Gtk::Orientation::HORIZONTAL, dynamic_cast<gPanthera::ContentTabBar*>(widget->get_stack()->get_parent()->get_first_child())->get_extra_child_function()); auto new_notebook = Gtk::make_managed<gPanthera::ContentNotebook>(new_stack, new_switcher);
@@ -374,6 +396,9 @@ public:
window->close(); delete window; }); controlled_page = nullptr; controlled_stack = nullptr; disable_controls();return true; };
@@ -416,7 +441,7 @@ public:
} }; // Go auto go_button = Gtk::make_managed<Gtk::Button>(_("Go"));go_button = Gtk::make_managed<Gtk::Button>(_("Go"));go_button->signal_clicked().connect(load_url_callback); url_bar->signal_activate().connect(load_url_callback); panthera->content_manager->signal_page_operated.connect([this, panthera](gPanthera::ContentPage *page) {
@@ -433,17 +458,23 @@ public:
controlled_page = page; controlled_stack = page->get_stack(); panthera->controlled_stack = page->get_stack(); url_bar->set_text(webkit_web_view_get_uri(WEBKIT_WEB_VIEW(page->get_child()->get_first_child()->gobj())));guint url_update_handler = g_signal_connect(page->get_child()->get_first_child()->gobj(), "notify", G_CALLBACK(panthera->notify_focused_callback), this);std::shared_ptr<sigc::connection> control_signal_handler = std::make_shared<sigc::connection>();*control_signal_handler = page->signal_control_status_changed.connect([this, page, control_signal_handler, url_update_handler](bool controlled) {if(!controlled) {control_signal_handler->disconnect();if(page->get_child() && page->get_child()->get_first_child() && WEBKIT_IS_WEB_VIEW(page->get_child()->get_first_child()->gobj())) {g_signal_handler_disconnect(page->get_child()->get_first_child()->gobj(), url_update_handler);}if(WEBKIT_WEB_VIEW(page->get_child()->get_first_child()->gobj())) { if(webkit_web_view_get_uri(WEBKIT_WEB_VIEW(page->get_child()->get_first_child()->gobj()))) { url_bar->set_text(webkit_web_view_get_uri(WEBKIT_WEB_VIEW(page->get_child()->get_first_child()->gobj())));} });guint url_update_handler = g_signal_connect(page->get_child()->get_first_child()->gobj(), "notify", G_CALLBACK(panthera->notify_focused_callback), this); std::shared_ptr<sigc::connection> control_signal_handler = std::make_shared<sigc::connection>(); *control_signal_handler = page->signal_control_status_changed.connect([this, page, control_signal_handler, url_update_handler](bool controlled) { if(!controlled) { control_signal_handler->disconnect(); if(page->get_child() && page->get_child()->get_first_child() && WEBKIT_IS_WEB_VIEW(page->get_child()->get_first_child()->gobj())) { g_signal_handler_disconnect(page->get_child()->get_first_child()->gobj(), url_update_handler); } } }); } enable_controls();}); history_viewer = Gtk::make_managed<HistoryViewer>(layout_manager, panthera->history_manager); history_viewer->signal_open_url.connect([this, panthera](const std::string &url) {
@@ -460,7 +491,7 @@ public:
reload_button->set_child(*Gtk::make_managed<Gtk::Image>(Gio::Icon::create("view-refresh-symbolic"))); reload_button->set_tooltip_text(_("Reload")); auto back_action = Gio::SimpleAction::create("go_back");back_action = Gio::SimpleAction::create("go_back");add_action(back_action); back_action->signal_activate().connect([this, panthera](const Glib::VariantBase&) { if(controlled_page) {
@@ -471,7 +502,7 @@ public:
}); back_button->set_action_name("win.go_back"); auto forward_action = Gio::SimpleAction::create("go_forward");forward_action = Gio::SimpleAction::create("go_forward");add_action(forward_action); forward_action->signal_activate().connect([this, panthera](const Glib::VariantBase&) { if(controlled_page) {
@@ -482,7 +513,7 @@ public:
}); forward_button->set_action_name("win.go_forward"); auto reload_action = Gio::SimpleAction::create("reload");reload_action = Gio::SimpleAction::create("reload");add_action(reload_action); reload_action->signal_activate().connect([this, panthera](const Glib::VariantBase&) { if(controlled_page) {
@@ -564,8 +595,29 @@ public:
std::cout << "Layout changed: " << layout_manager->get_layout_as_json() << std::endl; }); set_show_menubar(true); // As the window is initially empty, disable most actions disable_controls(); moving_connection = panthera->content_manager->signal_page_moving.connect([this, panthera](gPanthera::ContentPage *page) { if(page->get_root() == this) { controlled_page = nullptr; controlled_stack = nullptr; disable_controls(); } }); moved_connection = panthera->content_manager->signal_page_moved.connect([this, panthera](gPanthera::ContentPage *page) { if(page->get_root() == this) { panthera->content_manager->set_last_operated_page(page); page->get_stack()->set_visible_child(*page); enable_controls(); } }); } ~PantheraWindow() override { moving_connection.disconnect(); moved_connection.disconnect();} ~PantheraWindow() override = default;}; void PantheraWww::load_change_callback(WebKitWebView *object, WebKitLoadEvent load_event, gpointer data) {
@@ -621,6 +673,14 @@ void PantheraWww::notify_focused_callback(GObject *object, GParamSpec *pspec, gp
if(auto main_window = dynamic_cast<PantheraWindow*>(page->get_root())) { main_window->url_bar->set_text(webkit_web_view_get_uri(WEBKIT_WEB_VIEW(object))); } } else if(g_strcmp0(pspec->name, "title") == 0) { if(auto window = dynamic_cast<Gtk::Window*>(page->get_root())) { if(webkit_web_view_get_title(WEBKIT_WEB_VIEW(object))) { window->set_title(webkit_web_view_get_title(WEBKIT_WEB_VIEW(object))); } else { window->set_title(_("Untitled")); } }} } }
@@ -724,6 +784,7 @@ PantheraWindow *PantheraWww::make_window() {
void PantheraWww::on_startup() { bindtextdomain("panthera-www", "./locales"); textdomain("panthera-www"); content_manager = std::make_shared<gPanthera::ContentManager>();Gtk::Application::on_startup(); // Get search engines std::ifstream search_engines_file_in("search_engines.json");
@@ -738,6 +799,17 @@ void PantheraWww::on_startup() {
search_engines_file_out << empty_json.dump(4); } // Set window titles on tab switch content_manager->signal_page_operated.connect([this](gPanthera::ContentPage *page) { if(auto window = dynamic_cast<Gtk::Window*>(page->get_root())) { if(webkit_web_view_get_title(WEBKIT_WEB_VIEW(page->get_child()->get_first_child()->gobj()))) { window->set_title(webkit_web_view_get_title(WEBKIT_WEB_VIEW(page->get_child()->get_first_child()->gobj()))); } else { window->set_title(_("Untitled")); } } }); // Load settings new_tab_page = "about:blank"; std::ifstream settings_file_in("settings.json");