roundabout,
created on Tuesday, 20 May 2025, 15:57:53 (1747756673),
received on Tuesday, 20 May 2025, 15:57:57 (1747756677)
Author identity: vlad <vlad.muntoiu@gmail.com>
f949af4edce315aaf269fdfec8c7ae914c493bcb
.gitignore
@@ -1 +1,2 @@
/cmake-build-debug/ /cmake-build-debug.bak/
CMakeLists.txt
@@ -2,8 +2,11 @@ cmake_minimum_required(VERSION 3.30)
project(gpanthera) set(CMAKE_CXX_STANDARD 20) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--export-dynamic")add_library(gpanthera SHARED gpanthera.cc) add_library(test_plugin SHARED test_plugin.cc)add_executable(panthera-www panthera-www.cc) target_link_libraries(panthera-www gpanthera)
@@ -15,7 +18,10 @@ pkg_check_modules(GTKMM REQUIRED gtkmm-4.0)
pkg_check_modules(WebKit REQUIRED webkitgtk-6.0) find_package(nlohmann_json 3.10.0 REQUIRED) include_directories(${GTKMM_INCLUDE_DIRS})include_directories( ${GTKMM_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR} )link_directories(${GTKMM_LIBRARY_DIRS}) include_directories(${WebKit_INCLUDE_DIRS})
panthera-www.cc
@@ -13,6 +13,10 @@
#include <nlohmann/json.hpp> #include <iomanip> #include <sstream> #include <dlfcn.h> #include "plugin_api.h" using plugin_entrypoint_type = void(*)(void);std::string url_encode(const std::string &value) { // Thanks https://stackoverflow.com/a/17708801
@@ -44,7 +48,7 @@ struct SearchEngine {
if(pos == Glib::ustring::npos) { throw std::runtime_error("Invalid search engine URL: missing '%s' placeholder"); } auto new_url = url.substr(0, pos);auto new_url = url;new_url.replace(pos, 2, url_encode(query)); return new_url; }
@@ -410,6 +414,24 @@ protected:
}); add_action(close_tab_action); set_accels_for_action("app.close_tab", {"<Primary>W"}); // Load plugins std::ifstream plugin_file_in("plugins.json"); if(plugin_file_in) { std::string plugin_json((std::istreambuf_iterator<char>(plugin_file_in)), std::istreambuf_iterator<char>()); plugin_file_in.close(); auto json = nlohmann::json::parse(plugin_json); for(auto &plugin : json) { auto plugin_path = plugin["path"].get<std::string>(); load_plugin(plugin_path); } } else { plugin_file_in.close(); auto empty_json = nlohmann::json::array(); std::ofstream plugin_file_out("plugins.json"); plugin_file_out << empty_json.dump(4); plugin_file_out.close(); }} void on_activate() override {
@@ -439,10 +461,50 @@ public:
static Glib::RefPtr<PantheraWww> create() { return Glib::make_refptr_for_instance<PantheraWww>(new PantheraWww()); } std::shared_ptr<gPanthera::LayoutManager> get_layout_manager() { return layout_manager; } std::shared_ptr<gPanthera::ContentManager> get_content_manager() { return content_manager; } void load_plugin(const std::string &plugin_path) { void *handle = dlopen(plugin_path.c_str(), RTLD_LAZY | RTLD_GLOBAL); if(!handle) { std::cerr << "Failed to load plugin: " << dlerror() << std::endl; return; } auto entrypoint = (plugin_entrypoint_type)dlsym(handle, "plugin_init"); if(!entrypoint) { std::cerr << "Failed to find entrypoint in plugin: " << dlerror() << std::endl; dlclose(handle); return; } entrypoint(); }}; Glib::RefPtr<PantheraWww> app = nullptr; extern "C" { void panthera_log(const char *message) { std::cerr << message << std::endl; } void panthera_add_pane(const char *id, const char *label, GtkImage *icon, GtkWidget *pane) { auto pane_child = Glib::wrap(pane); auto icon_cc = Glib::wrap(icon); auto label_cc = Glib::ustring(label); auto id_cc = Glib::ustring(id); auto new_pane = Gtk::make_managed<gPanthera::DockablePane>(app->get_layout_manager(), *pane_child, id_cc, label_cc, icon_cc); app->get_layout_manager()->add_pane(new_pane); } } int main(int argc, char *argv[]) { gPanthera::init(); auto app = PantheraWww::create();app = PantheraWww::create();return app->run(argc, argv); }
plugin_api.h
@@ -0,0 +1,15 @@
#ifndef PLUGIN_API_H #define PLUGIN_API_H #include <gtk/gtk.h> #ifdef __cplusplus extern "C" { #endif void panthera_add_pane(const char *id, const char *label, GtkImage *icon, GtkWidget *pane); void panthera_log(const char *message); #ifdef __cplusplus } #endif #endif
test_plugin.cc
@@ -0,0 +1,5 @@
#include "plugin_api.h" extern "C" void plugin_init() { panthera_log("Plugin loaded"); }