如何在GJS中通过Gtk.Context绘制GTK主题窗口按钮?
问题:GJS Cairo上下文无法渲染GTK主题的窗口关闭按钮
我正在尝试从当前GTK活跃主题提取窗口按钮,在GJS的Cairo上下文内渲染,用于Gnome-Global-Menu。最开始我写了一段提取关闭按钮的代码:
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(); },
但这段代码完全没效果。后来我发现Ambiance主题的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")); }
而我的代码生成的Widget Path是.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 Shell面板的27像素)。
另外,我发现直接从实际Gtk Widget获取样式上下文的方式是可行的:
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');
想请教一下,我现在的代码还缺少什么步骤才能让按钮在Cairo上下文里正常渲染出来?
内容的提问来源于stack exchange,提问作者lestcape
相关产品推荐
相关产品推荐

