http://www.perlmonks.org?node_id=538765
DentArthurDent has asked for the wisdom of the Perl Monks concerning the following question:

Howdy fellow monks:

I'm making a little tray app in perl Gtk2 that puts up a menu of different hosts that I might want a shell window to. The only problem I have with it is that the submenu arrows show up on the right instead of the left like you would expect from a tray app.

I know this is probably a setting on the menu, but I can't find an example anywhere of how to set it. Can anybody help?

If it helps, the following is my current code:
#!/usr/bin/perl -w use Glib qw/TRUE FALSE/; use Gtk2; # load the Gtk-Perl module use Gtk2::TrayIcon; use strict; # a good idea for all non-trivial Perl scripts use Data::Dumper; # # To Do: perhaps submenus for hosts within clusters? DONE!! # set_locale Gtk2; # internationalize init Gtk2; # initialize Gtk-Perl # convenience variables for true and false my $false = 0; my $true = 1; # widget creation my $top_menu = new Gtk2::Menu(); my $menu_item; my $new_submenu; my $button; my %hosts; my %proggies; my $cur_host; my $img_dir="/opt/gnome/share/icons/hicolor/16x16/stock/net/"; my $menu_x; my $menu_y; my @menu_stack; # start a new submenu sub new_submenu { # get the highest menu in the stack my $name = shift; my $cur_submenu = $menu_stack[$#menu_stack]; $new_submenu = new Gtk2::Menu(); $menu_item = Gtk2::MenuItem->new_with_label($name); $menu_item->set_submenu($new_submenu); $menu_item->show; $cur_submenu->append($menu_item); push(@menu_stack,$new_submenu); } # stop adding stuff to the most nested menu sub end_submenu { pop(@menu_stack); } sub add_new_menu_entry { my $name = shift; my $cur_menu = $menu_stack[$#menu_stack]; $menu_item = Gtk2::MenuItem->new_with_label($name); $menu_item->signal_connect(activate => \&new_shell_cb, $name); $menu_item->show; # push this item on the current menu $cur_menu->append($menu_item); } sub new_shell_cb { my $button_clicked = shift; #my $cur_item = $menu->get_active; my $host; my $label; $label = $button_clicked->get_child; if ($label->isa('Gtk2::Label')) { $cur_host = $label->get_label; } if (exists($hosts{$cur_host})) { $host = $hosts{$cur_host}; } else { $host = $cur_host; } # start the shell unless (fork) { if (defined($proggies{$cur_host})) { exec("$ENV{HOME}/shell.csh","\#0000ff",$host,"root", $proggies{$cur_host}); } else { exec("$ENV{HOME}/shell.csh","\#0000ff",$host,"root"); } } } my $tray_img = Gtk2::Image->new_from_file($img_dir."stock_internet.png +"); my $tray = Gtk2::TrayIcon->new("shells"); my $eventbox = Gtk2::EventBox->new; $eventbox->add($tray_img); $tray->add($eventbox); $tray->show_all; $eventbox->signal_connect("button-press-event", \&handle_tray_press); open(SHELLS,"<$ENV{HOME}/.shells"); my $host_info; my $name; my $ip; my $first = 1; my $proggie; my $cur_menu; push(@menu_stack,$top_menu); $cur_menu = $menu_stack[$#menu_stack]; $menu_item = Gtk2::MenuItem->new_with_label("Exit"); $menu_item->signal_connect(activate => sub { exit(0); }, "Exit"); $menu_item->show; $cur_menu->append($menu_item); while ($host_info = <SHELLS>) { chomp($host_info); # ignore leading spaces to make config file prettier $host_info =~ s/^\s+//g; ($name, $proggie, $ip) = split(/\s+/,$host_info); # never pop the top menu if ($name eq "end" && scalar(@menu_stack) > 1) { end_submenu(); next; } if ($name eq "submenu") { new_submenu($proggie); next; } if ($first == 1) { $cur_host = $name; $first = 0; } if (defined($ip)) { $hosts{$name} = $ip; } if (defined($proggie)) { $proggies{$name} = $proggie; } add_new_menu_entry($name); } close(SHELLS); # Gtk event loop Gtk2->main; # Should never get here exit( 0 ); sub handle_tray_press { my $widget = shift; my $event = shift; $menu_x = $event->x_root - $event->x; $menu_y = $event->y_root - $event->y; $top_menu->popup(undef, undef, \&position_menu, 0, $event->button, $event->time); } sub position_menu { # Shamlessly stolen from Muine :-) my $x = $menu_x; my $y = $menu_y; my $monitor = $top_menu->get_screen->get_monitor_at_point($x,$y); my $rect = $top_menu->get_screen->get_monitor_geometry($monitor); my $space_above = $y - $rect->y; my $space_below = $rect->y + $rect->height - $y; my $requisition = $top_menu->size_request(); if ($requisition->height <= $space_above || $requisition->height <= $space_below) { if ($requisition->height <= $space_below) { $y = $y + $eventbox->allocation->height; } else { $y = $y - $requisition->height; } } elsif ($requisition->height > $space_below and $requisition->height > $space_above) { if ($space_below >= $space_above) { $y = $rect->y + $rect->height - $requisition->height; } else { $y = $rect->y; } } else { $y = $rect->y; } return ($x,$y,1); }
Thanks in advance!
----
My mission: To boldy split infinitives that have never been split before!