GTK docking interfaces and more

By using this site, you agree to have cookies stored on your device, strictly for functional purposes, such as storing your session and preferences.

Dismiss

Plugin support

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");
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        }