Search code examples
c++gtkgtkmmgtkmm3

Gtkmm3: Handling command line options and Gtk::Plug properly


I'm trying to interface with the xfce4-settings-manager which I was successfully able to do in the standard c gtk+-3.0 libraries, but I've been struggling to replicate it in gtkmm3. xfce4-settings-manager passes a --socked-id option to the client, and the client is meant to use a GtkPlug to connect to the socket via the id. As I mentioned before I was successful in writing it in C, and I've put that code in a github gist here. I prefer to use C++ as a means to learn the language in a more applied way and also because of its higher functionality to C.

I've struggled with the proper way to handle arguments to the proper way to use Gtk::Plug with hours of research and little results. If anyone can provide some insight into the proper way/documentation to handle command line arguments and GtkPlugs in gtkmm3 that would be greatly appreciated, and if you could provide any examples that would also be greatly appreciated. Thank you in advance!


Solution

  • Here is an example similar to yours, in C++ with Gtkmm 3:

    #include <string>
    
    #include <gtkmm.h>
    #include <gtkmm/plug.h>
    
    // Simple command line argument parser.
    //
    // Documented here:
    //
    //    https://gitlab.gnome.org/GNOME/glibmm/-/blob/master/examples/options/main.cc
    //
    class CmdArgParser : public Glib::OptionGroup
    {
    
    public:
    
        CmdArgParser(const std::string& p_name, const std::string& p_description, const std::string& p_help)
        : Glib::OptionGroup{p_name, p_description, p_help}
        {
            // Define the 'socket ID' argument options:
            Glib::OptionEntry socketIDArg;
            socketIDArg.set_long_name("socket-id");
            socketIDArg.set_short_name('s');
            socketIDArg.set_flags(Glib::OptionEntry::FLAG_IN_MAIN);
            socketIDArg.set_description("Settings manager socket");
    
            // Register it in the parser. It value will be recorded in m_socketID for later usage.
            add_entry(socketIDArg, m_socketID);
        }
    
        // Override this to handle errors. I skipped it for simplicity.
        // void on_error(Glib::OptionContext& context, const Glib::Error& error) override;
    
        ::Window GetSocketID() const
        {
            return m_socketID;
        }
    
    private:
    
        int m_socketID = 0;
    
    };
    
    // This is what is going to be plugged into xfce4-settings-manager:
    //
    // Documented here:
    //
    //     https://developer.gnome.org/gtkmm-tutorial/3.22/sec-plugs-sockets-example.html.en
    //
    class SettingsPlug : public Gtk::Plug
    {
    
    public:
    
        SettingsPlug(::Window p_socketID)
        : Gtk::Plug{p_socketID}
        {
            m_button.set_label("A plug with Gtkmm3!");
            add(m_button);
            show_all_children();
        }
    
    private:
    
        Gtk::Button m_button;
    };
    
    int main(int argc, char** argv)
    {
        auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example.plug");
    
        // Parse command line arguments and retreive socket ID:
        Glib::init();
        setlocale(LC_ALL, "");
        Glib::OptionContext context;
        
        CmdArgParser parser{
            "Socket ID",
            "Command line argument for socket ID communication.",
            "No help available, sorry"
        };
    
        context.set_main_group(parser);
        context.parse(argc, argv); 
    
        ::Window socketID = parser.GetSocketID();
    
        // Handle plug:
        SettingsPlug plug{socketID};
        plug.show();
      
        app->run(plug);
      
        return 0;
    }
    

    I have removed error handling and the usage of Glade files to simplify the code. You can build it with:

    g++ main.cpp -o example.out `pkg-config --cflags --libs gtkmm-3.0`