# Copyright (c) 1995-2003 Nick Ing-Simmons. All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. package Tk::MainWindow; use base qw(Tk::Toplevel); BEGIN { @MainWindow::ISA = 'Tk::MainWindow' } use strict; use vars qw($VERSION); $VERSION = '4.015'; # was: sprintf '4.%03d', q$Revision: #12 $ =~ /\D(\d+)\s*$/; use Tk::CmdLine; use Tk qw(catch); require Tk::Toplevel; use Carp; $| = 1; my %Windows = (); sub CreateArgs { my ($class,$args) = @_; my $cmd = Tk::CmdLine->CreateArgs(); my $key; foreach $key (keys %$cmd) { $args->{$key} = $cmd->{$key} unless exists $args->{$key}; } my %result = $class->SUPER::CreateArgs(undef,$args); my $name = delete($args->{'-name'}); unless (Tk::tainting) { $ENV{'DISPLAY'} = ':0' unless (exists $ENV{'DISPLAY'}); $result{'-screen'} = $ENV{'DISPLAY'} unless exists $result{'-screen'}; } return (-name => "\l$name",%result); } sub new { my $package = shift; if (@_ > 0 && $_[0] =~ /:\d+(\.\d+)?$/) { carp "Usage $package->new(-screen => '$_[0]' ...)" if $^W; unshift(@_,'-screen'); } croak('Odd number of args'."$package->new(" . join(',',@_) .')') if @_ % 2; my %args = @_; my $top = eval { bless Create($package->CreateArgs(\%args)), $package }; croak($@ . "$package->new(" . join(',',@_) .')') if ($@); $top->apply_command_line; $top->InitBindings; $top->SetBindtags; $top->InitObject(\%args); eval { $top->configure(%args) }; croak "$@" if ($@); if (($top->positionfrom||'') ne 'user' and ($top->sizefrom||'') ne 'user') { my $geometry = $top->optionGet(qw(geometry Geometry)); if ($geometry) { $top->geometry($geometry); } } $Windows{$top} = $top; return $top; } sub _Destroyed { my $top = shift; $top->SUPER::_Destroyed; delete $Windows{$top}; } sub InitBindings { my $mw = shift; $mw->bind('all','','focusNext'); # <> is named <> in Tcl/Tk $mw->eventAdd(qw[<> ]); # This is needed for XFree86 systems catch { $mw->eventAdd(qw[<> ]) }; # This seems to be correct on *some* HP systems. catch { $mw->eventAdd(qw[<> ]) }; $mw->bind('all','<>','focusPrev'); if ($mw->windowingsystem eq 'x11') { $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); } elsif ($mw->windowingsystem eq 'win32') { $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); } elsif ($mw->windowingsystem eq 'aqua') { $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); } elsif ($mw->windowingsystem eq 'classic') { $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); $mw->eventAdd(qw[<> ]); } # FIXME - Should these move to Menubutton ? my $c = ($Tk::platform eq 'unix') ? 'all' : 'Tk::Menubutton'; $mw->bind($c,'',['TraverseToMenu',Tk::Ev('K')]); $mw->bind($c,'','FirstMenu'); } sub Existing { my @Windows; foreach my $name (keys %Windows) { my $obj = $Windows{$name}; if (Tk::Exists($obj)) { push(@Windows,$obj); } else { delete $Windows{$name}; } } return @Windows; } END { if (Tk::IsParentProcess()) { foreach my $top (values %Windows) { if ($top->IsWidget) { # Tk data structuctures are still in place # this can occur if non-callback perl code did a 'die'. # It will also handle some cases of non-Tk 'exit' being called # Destroy this mainwindow and hence is descendants ... $top->destroy; } } } } sub CmdLine { return shift->command } sub WMSaveYourself { my $mw = shift; my @args = @{$mw->command}; # warn 'preWMSaveYourself:'.join(' ',@args)."\n"; @args = ($0) unless (@args); my $i = 1; while ($i < @args) { if ($args[$i] eq '-iconic') { splice(@args,$i,1); } elsif ($args[$i] =~ /^-(geometry|iconposition)$/) { splice(@args,$i,2); } } my @ip = $mw->wm('iconposition'); # print 'ip ',join(',',@ip),"\n"; my $icon = $mw->iconwindow; if (defined($icon)) { @ip = $icon->geometry =~ /\d+x\d+([+-]\d+)([+-]\d+)/; } splice(@args,1,0,'-iconposition' => join(',',@ip)) if (@ip == 2); splice(@args,1,0,'-iconic') if ($mw->state() eq 'iconic'); splice(@args,1,0,'-geometry' => $mw->geometry); # warn 'postWMSaveYourself:'.join(' ',@args)."\n"; $mw->command([@args]); } 1; __END__