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.
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?
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?
When I untick "Client side window decorations" and "Decorated" the black bar is gone. But the shadows and the rounded corners are also gone.
Is the way I'm doing this even the right one? How should it be done?
Okay, I figured it out.
To get this cool gnome bar in glade without having one of the aforementioned issues follow these steps:
Voila:
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.
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.
//is gnome-shell running?
std::string gnomeString = exec(
"pgrep -lx \"gnome-shell\" | head -1 | cut -d \" \" -f2"
);
//get version string
std::string gnomeVersionString = exec(
"gnome-shell --version | sed -e \"s/GNOME Shell //\""
);
//parse version string to int array; not 100% necessary, but nice to have
std::vector<int> gnomeVersion;
std::stringstream ss(gnomeVersionString); std::string item;
while (std::getline(ss, item, '.'))
gnomeVersion.push_back(std::atoi(item.c_str()));
//optional requirement for gnome-like header bar:
bool isGnome3 = gnomeString == "gnome-shell\n" &&
gnomeVersion.size() > 0 &&
gnomeVersion[0] >= 3;
//absolute requirement for gnome-like header bar:
bool correctGTKversion = gtk_major_version >= 3 &&
gtk_minor_version >= 10;
std::cout << "isGnome3: " << (isGnome3?"yes":"no") << "\n";
std::cout << "correctGTK+: " << (correctGTKversion?"yes":"no") << "\n";
std::cout << "gnome version: ";
for(int v : gnomeVersion)
std::cout << v << ".";
std::cout << "\n";