roundabout,
created on Monday, 30 June 2025, 14:25:55 (1751293555),
received on Monday, 30 June 2025, 14:25:58 (1751293558)
Author identity: vlad <vlad.muntoiu@gmail.com>
68cbca25dceaad0f844361b8dd1f9c882e71d377
gpanthera.cc
@@ -966,6 +966,7 @@ namespace gPanthera {
this->get_stack()->set_visible_child(*this->get_prev_sibling()); } this->redock(nullptr); content_manager->signal_page_closed.emit(this);} }
@@ -1008,7 +1009,7 @@ namespace gPanthera {
void ContentPage::redock(ContentStack *stack) { if(stack == nullptr) { content_manager->signal_page_moving.emit(this);content_manager->signal_page_closing.emit(this);if(this->stack) { this->stack->remove(*this); if(dynamic_cast<ContentNotebook*>(this->stack->get_parent()) && !this->stack->get_first_child()) {
@@ -1111,8 +1112,10 @@ namespace gPanthera {
this->last_operated_page->signal_control_status_changed.emit(false); } this->last_operated_page = page; page->signal_control_status_changed.emit(true);this->signal_page_operated.emit(page);if(page) { page->signal_control_status_changed.emit(true); this->signal_page_operated.emit(page); }} DockWindow *DockablePane::get_window() const {
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, signal_page_moving, signal_page_moved;sigc::signal<void(ContentPage*)> signal_page_operated, signal_page_moving, signal_page_moved, signal_page_closing, signal_page_closed;std::vector<ContentStack*> stacks; ContentManager();
panthera-www.cc
@@ -113,6 +113,20 @@ public:
} }; std::vector<WebKitWebView*> collect_webviews(Gtk::Widget const &root) { std::vector<WebKitWebView*> result; std::function<void(const Gtk::Widget&)> recurse = [&](const Gtk::Widget &widget) { gpointer gobj = G_OBJECT(widget.gobj()); if(WEBKIT_IS_WEB_VIEW(gobj)) { result.push_back(WEBKIT_WEB_VIEW(gobj)); } else for(auto *child = widget.get_first_child(); child; child = child->get_next_sibling()) { recurse(*child); } }; recurse(root); return result; } class HistoryViewer : public gPanthera::DockablePane { protected: std::shared_ptr<HistoryManager> history_manager;
@@ -290,6 +304,7 @@ private:
static void on_back_pressed(GtkGestureClick* gesture, int n_press, double x, double y, gpointer user_data); static void on_forward_pressed(GtkGestureClick* gesture, int n_press, double x, double y, gpointer user_data); static gboolean on_decide_policy(WebKitWebView* source, WebKitPolicyDecision* decision, WebKitPolicyDecisionType type, gpointer user_data); static void close_callback(WebKitWebView *source, gpointer user_data);protected: void on_startup() override;
@@ -392,10 +407,18 @@ public:
auto window = new gPanthera::ContentWindow(new_notebook); widget->redock(new_stack); window->present(); new_stack->signal_leave_empty.connect([window]() {window->close();delete window;});window->signal_close_request().connect([window]() { auto webviews = collect_webviews(*window); for(auto view : webviews) { webkit_web_view_try_close(view); } webviews = collect_webviews(*window); if(webviews.empty()) { // All documents have been closed safely, the window can be closed return false; } return true; }, false);controlled_page = nullptr; controlled_stack = nullptr; disable_controls();
@@ -445,6 +468,9 @@ public:
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) { if(!page) { return; }if(!page->get_child()) { return; }
@@ -613,6 +639,19 @@ public:
enable_controls(); } }); signal_close_request().connect([this]() { auto webviews = collect_webviews(*this); for(auto view : webviews) { webkit_web_view_try_close(view); } webviews = collect_webviews(*this); if(webviews.empty()) { // All documents have been closed safely, the window can be closed return false; } return true; }, false);} ~PantheraWindow() override { moving_connection.disconnect();
@@ -725,6 +764,26 @@ gboolean PantheraWww::on_decide_policy(WebKitWebView *source, WebKitPolicyDecisi
return false; } void PantheraWww::close_callback(WebKitWebView *source, gpointer user_data) { if(auto self = static_cast<PantheraWww*>(user_data)) { auto parent = gtk_widget_get_parent(gtk_widget_get_parent(GTK_WIDGET(source))); if(auto page = dynamic_cast<gPanthera::ContentPage*>(Glib::wrap(parent))) { if(page->get_next_sibling()) { page->content_manager->set_last_operated_page(static_cast<gPanthera::ContentPage*>(page->get_next_sibling())); page->get_stack()->set_visible_child(*page->get_next_sibling()); } else if(page->get_prev_sibling()) { page->content_manager->set_last_operated_page(static_cast<gPanthera::ContentPage*>(page->get_prev_sibling())); page->get_stack()->set_visible_child(*page->get_prev_sibling()); } webkit_web_view_terminate_web_process(source); if(page->content_manager->get_last_operated_page() == page) { page->content_manager->set_last_operated_page(nullptr); } page->redock(nullptr); } } } void PantheraWww::on_new_tab(gPanthera::ContentStack *stack, const Glib::ustring &url, bool focus, bool new_window) { if(!stack) { // Find the current area
@@ -747,6 +806,11 @@ void PantheraWww::on_new_tab(gPanthera::ContentStack *stack, const Glib::ustring
page_tab->append(*Gtk::make_managed<Gtk::Label>(_("Untitled"))); page_tab->set_spacing(4); auto page = Gtk::make_managed<gPanthera::ContentPage>(content_manager, stack, page_content, page_tab); page->signal_close.connect([webview]() { webkit_web_view_try_close(WEBKIT_WEB_VIEW(webview)); return true; }); g_signal_connect(webview, "close", G_CALLBACK(close_callback), this);g_signal_connect(webview, "notify", G_CALLBACK(notify_callback), this); g_signal_connect(webview, "load-changed", G_CALLBACK(load_change_callback), this); g_signal_connect(webview, "decide-policy", G_CALLBACK(on_decide_policy), this);
@@ -801,6 +865,9 @@ void PantheraWww::on_startup() {
// Set window titles on tab switch content_manager->signal_page_operated.connect([this](gPanthera::ContentPage *page) { if(!page) { return; }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())));