Search code examples
c++gtkgtkmmgtkmm3

How do I pack a Gtk::Entry into a Gtk::HeaderBar so the entry completely fills the header bar?


I'm making a program in gtkmm-3.0 which has a Gtk::HeaderBar as the title bar.

I'm trying to pack a Gtk::Entry into it using this code:

Gtk::HeaderBar headerBar;
Gtk::Entry entry;

headerBar.set_hexpand();
headerBar.set_halign((Gtk::Align)GTK_ALIGN_FILL);
entry.set_hexpand();
entry.set_halign((Gtk::Align)GTK_ALIGN_FILL);
headerBar.pack_start(uriEntry);
headerBar.set_show_close_button();

The entry is correctly packed, but it only fills half the space of the header bar, which is very confusing. Using headerBar.add(entry) or headerBar.pack_end(entry) does not help the slightest (The entry still fills half the space it's supposed to take).

Also, using headerBar.pack_start() with a Gtk::Button before the headerBar.pack_start(entry) line will put the button in its place, but the entry will stop the expansion at the same point that it stopped before, being shorter than before.

How can I make the entry fill the whole header bar?


Solution

  • The problem is that Gtk::HeaderBar also has a "title" widget taking space. You could set a title, resulting in this:

    enter image description here

    An you see why only half the screen was given to the entry. One workaround is to define your own, custom, header bar. Here is an extremely minimal example:

    #include <gtkmm.h>
    
    class MainWindow : public Gtk::ApplicationWindow
    {
    
    public:
    
        MainWindow();
    
    private:
    
        Gtk::Box m_customHeaderBar;
        Gtk::Entry m_entry;
    
    };
    
    MainWindow::MainWindow()
    {
        m_entry.set_hexpand_set(true);
        m_entry.set_hexpand();
    
        m_customHeaderBar.pack_start(m_entry);
    
        set_titlebar(m_customHeaderBar);
    }
    
    int main(int argc, char *argv[])
    {
        auto app = Gtk::Application::create(argc, argv, "org.gtkmm.examples.base");
      
        MainWindow window;
        window.show_all();
      
        return app->run(window);
    }
    

    Which results in this:

    enter image description here

    Of course, you will have to add a close button and everything yourself (I would recommend making a class). I will leave this part to you.