2

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

lestcape
  • 259
  • 2
  • 9

1 Answers1

1

The name of the element in CSS is the "CSS name", not the class name. You can set the CSS name in your class preamble:

const GtkButton = new GObject.Class({
    Name: 'button',
    CssName: 'button',
    Extends: Gtk.Button,
});

or, in new-style classes,

const GtkButton = GObject.registerClass({
    CssName: 'button',
}, class MyButton extends Gtk.Button {
});
ptomato
  • 56,175
  • 13
  • 112
  • 165
  • In the css definition i used a border-color: #333333; (is not in the default definition), then context.get_border_color(Gtk.StateFlags.NORMAL); give me the color value, to know if I'm connected to the css style or not. If i set the CssName: 'button', the color that is return me is 255, 255, 255, 255, so i'm not connected, but if i use the GTypeName: 'button' this return me the color 51, 51, 51, 255, So, this indicate me that I'm connected to the rigth css style. Please note that this only work on the last gjs, on older version i always recive not color. So, thanks but CssName won't work. – lestcape May 29 '18 at 01:56
  • Here i have a working example: https://github.com/lestcape/metacity-buttons (with the solution that work for me). Is probably easy replace this with the Gtk.WidgetPath implementation and you will see all problems, from your self. If you concidered it a bug, i can open an issue in gjs. – lestcape May 29 '18 at 02:45
  • This changed from the gtype name to the CSS name in GTK 3.20, I think. So if you're running in GTK 3.18 then it will be different. Where's the CSS in your example? – ptomato May 29 '18 at 03:05
  • I used the 3.22.30-1ubuntu1 package and is not working. I just edit the ambiance theme directly: /usr/share/themes/Ambiance/gtk-3.20/gtk-widgets.css and then set the Ambiance theme in gnome tweek tools. It's the same with/without add a Gtk.CssProvider. By default is used the current active Gtk.CssProvider and this is the current active theme. The previus link is an extension to extract the window buttons with base on the current active theme. See a video of the extension: https://www.youtube.com/watch?v=7CnoMEM44Do – lestcape May 29 '18 at 03:19