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

Hello all,

I'm trying to accomplish the apparently simple task of creating a GTK window that's the size I want it to be, and not the size the desktop environment wants it to be.

I'm working with the Perl-GTK bindings on an Ubuntu box, but I'm really looking for solutions that will work on a range of different OSs.

Can anyone point me in the right direction with the following problems?

1. How can I get the actual available size of the desktop? The following code gives the maximum resolution, but the size of the desktop actually available to my GTK windows is somewhat less (it is reduced by one taskbar in Windows; by two in Ubuntu.)

my $screen = $windowHandle->get_screen; my $width = $screen->get_width; my $height = $screen->get_height;

2. The following code creates a window and resizes it. However, the specified size seems to be applied only to the window's client area, not the whole window. (Example: ff the client area is 300x200, the actual size of the window is likely to be something like 300x215.)

my $windowHandle = Gtk2::Window->new('toplevel'); $windowHandle->signal_connect('delete_event' => sub { exit; }); windowHandle->resize($self->currentWidth, $self->currentHeight);

My question is, how can I resize the window, so that it is actually 300x200?

3. I've found that GTK windows like to resize themselves whenever they feel the need. One particularly annoying example is a window containing a scrollwindow, which contains a textview. Word wrapping is turned on, but as soon as the first text is written, the width of the window increases by about 4 pixels.

Is there a general (meaning, 'elegant') way to discourage GTK windows from resizing themselves?

Replies are listed 'Best First'.
Re: gtk window sizes
by zentara (Cardinal) on Apr 08, 2011 at 16:02 UTC
    1. How can I get the actual available size of the desktop? The following code gives the maximum resolution, but the size of the desktop actually available to my GTK windows is somewhat less (it is reduced by one taskbar in Windows; by two in Ubuntu.)

    I'm afraid to say from my experience, that you have to figure out where the taskbars are, get their window placements, and account for them. When you say take me to (0,0) on the screen, it will go to (0,0). If another app, like a taskbar is there, it's up to you to avoid the taskbar area, or layer your app over the taskbar.

    There is a tool for this, called Gnome2::Wnck, and here is a very crude usage. The while(1)hack I used to repeat this is awful, but it shows what is happening.

    #!/usr/bin/perl use warnings; use strict; use Gtk2; use Gnome2::Wnck; Gtk2->init(); while (1) { sleep 1; Gtk2->main_iteration while Gtk2->events_pending; my $screen = Gnome2::Wnck::Screen->get(0); $screen->force_update(); my @windows_list = $screen->get_windows(); foreach my $window (@windows_list) { my $name = $window->get_name(); print "name = $name\n"; } print "\n\n"; sleep 10; }

    2. The following code creates a window and resizes it. However, the specified size seems to be applied only to the window's client area, not the whole window. (Example: ff the client area is 300x200, the actual size of the window is likely to be something like 300x215.)

    The extra pixels are added by the window manager, to give you window manager controls. If you want your window to be exactly what you specify, use no decorations.

    #!/usr/bin/perl use warnings; use strict; use Glib qw/TRUE FALSE/; use Gtk2 '-init'; # works on any ICCWM compliant window manager my $window = Gtk2::Window->new(); $window->set_decorated(0); Gtk2::Window::set_decorated($window, 0); print $window->get_decorated(),"\n"; $window ->signal_connect( 'destroy' => \&delete_event ); $window->set_border_width(10); $window->set_size_request(300,200); my $vbox = Gtk2::VBox->new( FALSE, 6 ); $window->add($vbox); $vbox->set_border_width(2); my $hbox= Gtk2::HBox->new( FALSE, 6 ); $vbox->pack_end($hbox,FALSE,FALSE,0); $hbox->set_border_width(2); my $button = Gtk2::Button->new_from_stock('gtk-quit'); $hbox->pack_end( $button, FALSE, FALSE, 0 ); $button->signal_connect( clicked => \&delete_event ); $window->set_position('center'); $window->show_all(); Gtk2->main; ##################################### sub delete_event { Gtk2->main_quit; return FALSE; }
    Also remember, (-1,-1) will bring you to the lower right hand bottom corner. But when going from that direction, you must be aware of setting the gravity.
    #!/usr/bin/perl use warnings; use strict; use Glib qw/TRUE FALSE/; use Gtk2 '-init'; my $window = Gtk2::Window->new('toplevel'); $window->set_title('Z'); $window ->signal_connect( 'destroy' => \&delete_event ); $window->set_border_width(10); my $width = 300; my $height = 200; $window->set_size_request($width,$height); $window->set_gravity('GDK_GRAVITY_SOUTH_EAST'); #this avoids the offset due to window decorations my $vbox = Gtk2::VBox->new( FALSE, 6 ); $window->add($vbox); $vbox->set_border_width(2); my $hbox= Gtk2::HBox->new( FALSE, 6 ); $vbox->pack_end($hbox,FALSE,FALSE,0); $hbox->set_border_width(2); my $button = Gtk2::Button->new_from_stock('gtk-quit'); $hbox->pack_end( $button, FALSE, FALSE, 0 ); $button->signal_connect( clicked => \&delete_event ); #$window->set_position('center'); my ($xscr, $yscr) = (Gtk2::Gdk->screen_width, Gtk2::Gdk->screen_height +); print "$xscr $yscr\n"; $window->move($xscr - $width, $yscr - $height); $window->show_all(); Gtk2->main; ##################################### sub delete_event { Gtk2->main_quit; return FALSE; }

    Hope that gets you going. :-)

    As far as widgets resizing themselves, it is probably a matter of improper packing, and whether you have the homogeneous, spacing, expand, fill, padding settings correct for what behavior you want. Also see gtk2 widgets positions Here are a few more scripts which may be of interest to you.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: gtk window sizes
by ronlewis (Initiate) on Apr 19, 2011 at 16:52 UTC
    As far as widgets resizing themselves, it is probably a matter of improper packing, and whether you have the homogeneous, spacing, expand, fill, padding settings correct for what behavior you want.

    That's what I thought - improper packing.

    I've burst a few brain cells trying to work out what the problem can be - I wonder if anyone can spot something obviously wrong?

    The two scripts below are identical, except that the first writes some text to the window, and the second doesn't. The windows should be the same size, but the first is slightly wider.