我是
gjs
和gtk
的新手,所以这可能是非常基本的,但我没有发现任何其他与此相关的问题。
在尝试了解 gtk 和 gdk 的 gjs 绑定时,我想编写一个小脚本来记录将打开窗口的监视器的尺寸,因此我想出了以下脚本:
import Gtk from 'gi://Gtk?version=4.0'
import Gdk from 'gi://Gdk?version=4.0'
// Gtk needs to be initialized to get a non-null default display, I think
Gtk.init()
const {Display, Surface} = Gdk
const display = Display.get_default()
const surface = Surface.new_toplevel(display)
const {geometry: {width, height}} = display.get_monitor_at_surface(surface)
console.log(`Width: ${width}`)
console.log(`Height: ${height}`)
surface.destroy()
虽然此脚本成功退出(状态代码 0),但它会记录类似以下行的内容:
(gjs:12345): Gjs-CRITICAL **: 00:00:00.000: Object 0x112233445566 of type GdkWaylandToplevel has been finalized while it was still owned by gjs, this is due to invalid memory management.
但是,以下实验让我对如何适当修改此脚本感到困惑:
surface.destroy()
行会记录一条警告:losing last reference to undestroyed surface
,这似乎很公平,因为该表面没有被破坏。console.log('appended')
记录该消息,因此销毁表面不会引发任何错误(我在确保原始脚本的状态代码为 0 之前对此进行了测试);但是,我不知道其他事情是否可能会触发错误(例如运行 GLib 主循环)。在此脚本中管理内存的适当方法是什么?
编辑:
在集成获取的尺寸以运行具有适当大小的嵌套 Wayland 会话时,我意识到当脚本自行完成时会记录关键消息,而不是在通过 Ctrl+C 中止时记录关键消息。不记录任何不相关消息的最小工作示例是:
import Gtk from 'gi://Gtk?version=4.0'
import Gdk from 'gi://Gdk?version=4.0'
import Gio from 'gi://Gio'
Gtk.init()
const {Display, Surface} = Gdk
const {Subprocess, SubprocessFlags: {SEARCH_PATH_FROM_ENVP}} = Gio
Gio._promisify(Subprocess.prototype, 'wait_async', 'wait_finish')
const display = Display.get_default()
const surface = Surface.new_toplevel(display)
const {geometry: {width, height}} = display.get_monitor_at_surface(surface)
surface.destroy()
await Subprocess.new(
['sleep', '5'],
SEARCH_PATH_FROM_ENVP
).wait_async(null)
正如之前所解释的,如果我们在运行此脚本后等待 5 秒,脚本会自行完成并记录关键消息;但是,如果我们在此之前按 Ctrl+C,它将中止并且该消息永远不会被记录。
在销毁表面之前执行
surface.ref()
消除了该消息。
import Gtk from 'gi://Gtk?version=4.0'
import Gdk from 'gi://Gdk'
// Gtk needs to be initialized to get a non-null default display, I think
Gtk.init()
const {Display, Surface} = Gdk
const display = Display.get_default()
const surface = Surface.new_toplevel(display)
const {geometry: {width, height}} = display.get_monitor_at_surface(surface)
console.log(`Width: ${width}`)
console.log(`Height: ${height}`)
surface.ref()
surface.destroy()
我仍然不明白为什么,但根据@andy.holmes的建议,我在
gjs
项目上提出了一个问题。我将根据我收到的相关反馈更新此答案。