我有一个 Perl Gtk3 脚本,我想在其中获取当前显示器上打开的所有 X11 窗口的列表。
到目前为止,我已经:
#!/usr/bin/perl -w
package Gtk3::Gdk::X11;
use strict;
use Glib::Object::Introspection;
Glib::Object::Introspection->setup(basename => 'GdkX11', version => '3.0', package => 'Gtk3::Gdk');
package main;
use strict;
use Gtk3 -init;
use Data::Dumper;
my $x_root = Gtk3::Gdk::x11_get_default_root_xwindow();
print "x_root = " . Dumper $x_root;
my $gdk_screen = Gtk3::Gdk::Screen::get_default();
print "gdk_screen = " . Dumper $gdk_screen;
my $wm_name = $gdk_screen->get_window_manager_name;
print "wm_name = '$wm_name'\n";
my $gdk_display = Gtk3::Gdk::Display::open(':0');
print "gdk_display = " . Dumper $gdk_display;
my $gdk_root = Gtk3::Gdk::X11Window::foreign_new_for_display($x_root, $gdk_display, $x_root);
print "gdk_root = " . Dumper $gdk_root;
my $a_net_client_list = Gtk3::Gdk::atom_intern('_NET_CLIENT_LIST', 1);
print "a_net_client_list = " . Dumper $a_net_client_list;
my $a_window = Gtk3::Gdk::atom_intern('WINDOW', 1);
print "a_window = " . Dumper $a_window;
my $wins = Gtk3::Gdk::property_get($gdk_root, $a_net_client_list, $a_window, 0, 1024, 0);
print "wins = " . Dumper $wins;
但这会导致:
x_root = $VAR1 = 2443;
gdk_screen = $VAR1 = bless( {}, 'Gtk3::Gdk::X11Screen' );
wm_name = 'Xfwm4'
gdk_display = $VAR1 = bless( {}, 'Gtk3::Gdk::X11Display' );
gdk_root = $VAR1 = bless( {}, 'Gtk3::Gdk::X11Window' );
a_net_client_list = $VAR1 = bless( do{\(my $o = 129)}, 'Gtk3::Gdk::Atom');
a_window = $VAR1 = bless( do{\(my $o = 33)}, 'Gtk3::Gdk::Atom' );
**
ERROR:gperl-i11n-marshal-struct.c:43:struct_to_sv: assertion failed: (!own)
Aborted (core dumped)
如果有办法在 Perl 中使用 libwnck3,那也可能有效。
我找到了一个解决方案(虽然不是我喜欢的):
#!/usr/bin/perl -w
use strict;
use Gtk3 -init;
use Glib::Object::Introspection;
Glib::Object::Introspection->setup(basename => 'GdkX11', version => '3.0', package => 'Gtk3::Gdk');
Glib::Object::Introspection->setup(basename => 'Wnck', version => '3.0', package => 'Wnck');
my $screen = Wnck::Screen::get_default();
$screen->force_update;
for my $win (@{$screen->get_windows}) {
my $name = $win->get_name;
my $ws = $win->get_workspace;
my $w = $ws ? $ws->get_number : -1;
printf "(%04d, %04d) %04dx%04d:%2s $name\n", $win->get_geometry, $w;
}
我不想使用 Wnck 的原因是因为 文档说:
the use of this library is relatively expensive in terms of resources
。 我的应用程序不需要 Wnck 提供的大部分功能,所以它有点矫枉过正。