Scindix Scindix - 1 month ago 20
C++ Question

Get gnome-3-like windows with custom headerbar

My Problem



I'm working with Anjuta/gtkmm/C++ and want to design a program that looks similar to other gnome 3 programs.

This includes that big draggable Headerbar with custom buttons on it and other visual effects like the bigger background shadow behind the window.

Black Bar Issue



So far I discovered the
GtkHeaderBar
Widget. I also discovered that you can use
main_win->set_titlebar(*header_bar);
to make it draggable. Furthermore I ticked the "Client side window decorations" check box in the glade plugin (inside Anjuta).

However now it looks like in the image below. How do I get rid of that black bar?

Compatibility with other Desktops



Another question is how to maintain compatibility with other DEs? My bet would be to have two different glade/xml files (or one part of it in two external files). One contains the code that generates the gnome-3-like window and one that generates a normal one. When loading the program it is decided which file should be loaded based on the fact whether it is running under gnome 3 or any other desktop environment. But what is the best way to determine if the DE is gnome 3?

screenshot with black bar on top

Update



When I untick "Client side window decorations" and "Decorated" the black bar is gone. But the shadows and the rounded corners are also gone.

enter image description here

Is the way I'm doing this even the right one? How should it be done?

Answer

Okay, I figured it out.

Black bar issue

To get this cool gnome bar in glade without having one of the aforementioned issues follow these steps:

  1. Tick "Client side window decorations" in the "General tab" in the window properties. Make sure that "Decorated" is ticked, too, even if it is greyed out. You can tick (or untick) it while "Client side window decorations" is unticked.

enter image description here

  1. A new space at the top of the window should appear

enter image description here

  1. Place a header bar inside it

enter image description here

  1. (Optionally) Tick "Show window controls" in the "General" tab of its properties and give it a title and a subtitle

enter image description here

Voila:

enter image description here

Note that something like main_win->set_titlebar(*header_bar); isn't even needed. There's nothing specific that you have to do in your code to make this work.

Compatibility

It seems the only way to maintain compatibility is the way already described in the question post. The best way to determine if gnome-shell is running or if the right version of GTK+ is used is the one below. (Or at least the best one I came up with). It uses the function exec from here: stackoverflow.

std::string gnomeString = exec("echo \"$GDMSESSION|$XDG_CURRENT_DESKTOP\"");
//optional requirement for gnome-like header bar:
bool isGnome = gnomeString == "gnome|GNOME\n" ||
               gnomeString == "gnome-shell|GNOME\n";
//absolute requirement for gnome-like header bar:
bool correctGTKversion = gtk_major_version >= 3 && gtk_minor_version >= 10;

std::cout << "isGnome: " << (isGnome?"yes":"no") << "\n";
std::cout << "correctGTK+: " << (correctGTKversion?"yes":"no") << "\n";