Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have two Gnome2::Wnck problems, closely related.

1. Some time ago, I sought the wisdom of the Perl Monks for a way to detect the size of window controls.

The solution offered was to use Gnome2::Wnck. I drew two test Gtk2::Windows, at opposite corners of the desktop, at a known position. I use this to create a window of a fixed size:

my $testWindow = Gtk2::Window->new('toplevel'); $testWindow->set_title('my_test_window'); $testWindow->set_size_request(100, 100)

Then I used WNCK to give me a list of all windows currently open:

my $screen = Gnome2::Wnck::Screen->get(0); $screen->force_update(); my @winList = $screen->get_windows();

Then I looked for the right window:

foreach my $win (@winList) { if ($win->get_name() eq 'my_test_window') { # Success! } }

Then I got the right window's geometry:

foreach my $win (@winList) { if ($win->get_name() eq 'my_test_window') { # Success! my @geometryList = $win->get_client_window_geometry(); } }

From @geometryList, I can work out the window's actual size, and two of the four window controls I need. By using two windows at opposite corners of the desktop, I can get the size of all four window controls.

My problem is that, for reasons I don't understand, this algorithm sometimes fails. The call to $screen->get_windows() returns a list of windows which sometimes contains our test window, and sometimes doesn't.

The attached file (wncktest.pl) is an exaggerated version of this algorithm. It creates ten windows in slightly different positions, and reporting on whether the window can be found in WNCK's window list, or not.

Usually, the first, second or third window is not found; thereafter, none of the remaining windows are found. No doubt the reason for failure is obvious but not to me. Help, please!

2. My Gtk2::Windows are being moved around a lot. I create a window like this:

    my $gtkWin = Gtk2::Window->new('toplevel');

Again, I was advised to use Gnome2::Wnck to get the windows into the position I want, with calls such as

$wnckWin->move() $wnckWin->resize() $wnckWin->set_geometry()

A small problem is that I can't be sure that $gtkWin (which is set to a value like Gtk2::Window=HASH(0x8d51b78) ) and $wnckWin (which is set to a value like Gnome2::Wnck::Window=HASH(0x79f21c0) ) refer to the same window. Of course, I can query the windows' titles:

$gtkWin->get_title() $wnckWin->get_name()

...but this is asking for trouble if there are two window on the desktop with the same title. (What happens, for example, if two copies of the same perl script are executed at the same time, producing two copies of each Gtk2::Window?)

Is there some clever way to be *certain* that $gtkWin and $wnckWin are the same window?

#!/usr/bin/perl -w use strict; use warnings; use diagnostics; use Glib qw/TRUE FALSE/; use Gtk2 '-init'; use Gnome2::Wnck; # #################################################################### +########## # Gnome2::Wnck test # # Creates ten Gtk2::Windows, each in a slightly different position # Asks WNCK for a list of all open windows, and sees if our test windo +w is among them # This test fails, usually on the second or third window # # #################################################################### +########## LOOP: for (my $count = 1; $count <= 10; $count++) { # Each windows has a different title my $title = 'my_test_window_' . $count; # Create a Gtk2::Window my $testWindow = Gtk2::Window->new('toplevel'); $testWindow->signal_connect('delete_event' => sub { exit; }); $testWindow->set_title($title); $testWindow->set_size_request(100, 100); $testWindow->show(); # Move each window to a different position than the previous one $testWindow->move((50 * $count), (50 * $count)); # Now try to get the created window via WNCK # Set up Gnome2::Wnck Gtk2->main_iteration while Gtk2->events_pending; my $screen = Gnome2::Wnck::Screen->get(0); $screen->force_update(); # Get a list of all open windows my @windowList = $screen->get_windows(); # Check each window, looking for the one named $title foreach my $window (@windowList) { if ($window->get_name() eq $title) { print "Success! I found the right window!\n"; print "Window $window, named " . $window->get_name() . "\n +"; next LOOP; } } print "Failure! I couldn't find the window $title\n"; } # Main event loop Gtk2->main();

Replies are listed 'Best First'.
Re: Finding windows with WNCK
by zentara (Cardinal) on Jul 24, 2012 at 13:49 UTC
    My problem is that, for reasons I don't understand, this algorithm sometimes fails. The call to $screen->get_windows() returns a list of windows which sometimes contains our test window, and sometimes doesn't.

    Without analyzing your code, I would remind you that the window lists which WNCK returns depends on the virtual desktop you are on. You have to cycle thru the virtual desktops, and get the window list from each. I have a program that fails like that, it used WNCK to get the Mozilla x_window_id, but it only worked if the Perl script was executed from the same virtual desktop as Mozilla.

    I hope it made sense, it seems like common sense to me. :-)


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh