如何在gjs中从Gtk.Context中修改窗口按钮
我正试图从当前的gtk活动主题中提取windows按钮,并在gjs中的cairo上下文中呈现它,以便在Gnome全局菜单()中使用。例如,我使用了一个代码来提取关闭按钮如何在gjs中从Gtk.Context中修改窗口按钮,gtk,cairo,gnome-shell,gnome-shell-extensions,gjs,Gtk,Cairo,Gnome Shell,Gnome Shell Extensions,Gjs,我正试图从当前的gtk活动主题中提取windows按钮,并在gjs中的cairo上下文中呈现它,以便在Gnome全局菜单()中使用。例如,我使用了一个代码来提取关闭按钮 this.actor = new St.DrawingArea(); this.actor.connect('repaint', Lang.bind(this, this._onRepaint)); _onRepaint: function(area) { let cr = area.get_context();
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();
},
这是我的第一次近似,但它不起作用。我发现氛围主题中的css是这样的:
.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"));
}
生成我的代码的路径具有以下格式:
.titlebar GtkButton.titlebutton.close
这是因为gjs中Gtk.Button的GType返回我GtkButton而不是Button,就像在主题中一样。因此,我创建了一个助手类:
const GtkButton = new GObject.Class({
Name: 'button',
GTypeName: 'button',
Extends: Gtk.Button,
_init: function(params) {
this.parent(params);
},
});
而不是:
let pos2 = path.append_type(Gtk.Button);
我补充说:
let pos2 = path.append_type(GtkButton);
然后我的路径和css属性匹配,但在我的cairo上下文中也没有显示任何内容。绘图区域的宽度和高度是gnome外壳面板27像素的大小
那么,这里缺少了什么
另一方面,如果我直接从Gtk.widgets获取上下文,我想要的就是:
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');
使用最后一个代码实现的示例如下:可以在此处看到显示其工作的视频:CSS中元素的名称是“CSS名称”,而不是类名。您可以在类前言中设置CSS名称:
const GtkButton = new GObject.Class({
Name: 'button',
CssName: 'button',
Extends: Gtk.Button,
});
或者,在新式课堂上
const GtkButton = GObject.registerClass({
CssName: 'button',
}, class MyButton extends Gtk.Button {
});
在css定义中,我使用了边框颜色:#333333;(不在默认定义中),然后是context.get_border_color(Gtk.StateFlags.NORMAL);给我颜色值,知道我是否连接到css样式。如果我设置CssName:“button”,则返回我的颜色为255、255、255、255,因此我未连接,但如果我使用GTypeName:“button”,则返回我的颜色为51、51、51、255,这表示我已连接到rigth css样式。请注意,这只适用于最后的gjs,在旧版本上,我始终不接受颜色。所以,谢谢,但是CssName不起作用。这里我有一个有效的例子:(使用适合我的解决方案)。用Gtk.WidgetPath实现替换它可能很容易,您将从自己的角度看到所有问题。如果你认为它是一个bug,我可以在gjs中打开一个问题。我认为这在GTK3.20中从gtype名称更改为CSS名称。因此,如果你在GTK3.18运行,那么它将是不同的。您的示例中的CSS在哪里?我使用了3.22.30-1ubuntu1包,但不起作用。我只是直接编辑环境主题:/usr/share/themes/ambiance/gtk-3.20/gtk-widgets.css,然后在gnome tweek工具中设置环境主题。添加/不添加Gtk.CssProvider也是一样的。默认情况下,用于当前活动的Gtk.CssProvider,这是当前活动的主题。previus链接是基于当前活动主题提取窗口按钮的扩展。请参阅扩展的视频: