I' m trying to extract the windows buttons from the current gtk active theme and render it inside a cairo context in gjs, to be used in the Gnome-Global-Menu (https://gitlab.com/lestcape/Gnome-Global-AppMenu). As an example, i have one code that I use, to extract the close button.
this.actor = new St.DrawingArea();
this.actor.connect('repaint', Lang.bind(this, this._onRepaint));
_onRepaint: function(area) {
let cr = area.get_context();
let [width, height] = area.get_surface_size();
let provider = Gtk.CssProvider.get_default();
let path = new Gtk.WidgetPath();
let pos1 = path.append_type(Gtk.HeaderBar);
let pos2 = path.append_type(Gtk.Button);
path.iter_add_class(pos1, 'titlebar');
path.iter_add_class(pos2, 'titlebutton');
path.iter_add_class(pos2, 'close');
let context = new Gtk.StyleContext();
context.set_screen(Gdk.Screen.get_default());
context.set_path(path);
context.save();
context.set_state(Gtk.StateFlags.NORMAL);
Gtk.render_background(context, cr, 0, 0, width, height);
Gtk.render_frame(context, cr, 0, 0, width, height);
context.restore();
},
This was my firts aproximation, but it not work. I detect that the css inside the Ambiance theme is something like that:
.titlebar button.titlebutton.close {
border-color: #333333;
color: #323112;
-gtk-icon-shadow: 0 1px rgba(255, 255, 255, 0.25);
background-image: -gtk-scaled(url("assets/windowbutton-close.png"),
url("assets/windowbutton-close@2.png"),
url("assets/windowbutton-close@3.png"),
url("assets/windowbutton-close@4.png"));
}
And the path that generate my code have this format:
.titlebar GtkButton.titlebutton.close
This happend because the GType of the Gtk.Button in gjs return me GtkButton and not button, like in the theme. So, i create a helper class:
const GtkButton = new GObject.Class({
Name: 'button',
GTypeName: 'button',
Extends: Gtk.Button,
_init: function(params) {
this.parent(params);
},
});
And then instead of:
let pos2 = path.append_type(Gtk.Button);
I add:
let pos2 = path.append_type(GtkButton);
Then my path and the css properties match, but also nothing is displayed in my cairo context. The width and the height of the drawing area is the size of the gnome shell panel 27 pixels.
So, what it's missing here?
For the another hands, if i get the context directly from the Gtk.widgets what i want, just is working:
let headerWidget = new Gtk.HeaderBar();
let buttonWidget = new Gtk.Button();
let context = headerWidget.get_style_context();
context.add_class('titlebar');
headerWidget.add(buttonWidget);
context = buttonWidget.get_style_context();
context.add_class('titlebutton');
context.add_class('close');
An example implemented with the last code is here: https://gitlab.com/lestcape/metacity-buttons and a video to show it working can be see here: https://www.youtube.com/watch?v=7CnoMEM44Do&t=18s