Hi,

Attached test script gives working Wx::TaskBarIcon on both Linux and Windows for me.

I think the main issue using Wx::TaskBarIcon is that you cannot call $taskbaricon->Destroy() within an event handler for the taskbar icon itself (hence the AddPendingEvent action in the example).

I actually find this to be the case for many windows under none MSW platforms. If you destroy a window from within one of its own event handlers, then you get a segmentation fault or bus error. I haven't really tested this out fully because avoiding calling 'Destroy' directly is such a simple workaround.

Hope it helps

Mark


On 23/06/2011 02:05, herbert breunung wrote:
hai nice people here

its understood that you have to

     $win->{'tb_icon'} = Wx::TaskBarIcon->new( );
     $win->{'tb_icon'}->SetIcon( Wx::GetWxPerlIcon() );
     #$win->{'tb_icon'}->RemoveIcon;
     $win->{'tb_icon'}->Destroy;

but this works only under windows,
linux gives you a nice memory access error.

i think this is a bug

further more it cant be destroyed on app shutdown, but
maybe i didnt found the solution and have to derive from it or something,
cant find it in the dmeo app.

thanks for reading
use strict;
use warnings;

#------------------------------------

package TaskBarIconTest::Frame;

#------------------------------------
use Wx qw( :everything );
use base qw( Wx::Frame );
use Wx::Event qw( EVT_CLOSE );


sub new {
    my $class = shift;
    my $self = $class->SUPER::new(undef, wxID_ANY, 'TaskBarIconTest::Frame');
    EVT_CLOSE($self, \&OnEvtClose);
    return $self;
}

sub OnEvtClose {
    my($self, $event) = @_;
    $event->Skip(1); # really close
    # application won't end if taskbar still exists;
    wxTheApp->destroy_taskbar;
}

#------------------------------------

package TaskBarIconTest::App;

#------------------------------------

use Wx qw( :everything );
use base qw( Wx::App );
use Wx::Event qw( EVT_COMMAND EVT_MENU EVT_TASKBAR_CLICK );

our $EVT_TASKBAREXIT_ID = Wx::NewEventType; 

sub new {
    my $class = shift;
    my $self = $class->SUPER::new();
    return $self;
}

sub OnInit {
    my $self = shift;
    my $mwin = TaskBarIconTest::Frame->new();
    $self->SetTopWindow($mwin);
    $self->create_taskbar;
    EVT_COMMAND($self, -1, $EVT_TASKBAREXIT_ID, \&OnEvtTaskBarExit );
    return 1;
}

sub OnEvtTaskBarExit {
    my ($self, $event) = @_;
    if( my $mwin = $self->GetTopWindow ) {
        $mwin->Close;
    }
}

sub create_taskbar {
    my $self = shift;
    return if Wx::wxMAC();
    
    $self->{taskbar} = Wx::TaskBarIcon->new();
    
    EVT_TASKBAR_CLICK( $self->{taskbar}, sub {
        my ($taskbar, $event) = @_;
        my $menu = Wx::Menu->new('TaskBarIcon Test');
        my $m_item = Wx::MenuItem->new($menu, wxID_ANY, '&Toggle Main Window 
View');
        $menu->Append( $m_item );
        EVT_MENU( $taskbar, $m_item,
            sub {
                my($this, $event) = @_;
                my $mwin = wxTheApp->GetTopWindow;
                return if !$mwin;
                my $showval = ( $mwin->IsShown ) ? 0 : 1;
                $mwin->Show($showval);
            }
        );
        $m_item = Wx::MenuItem->new($menu, wxID_ANY, 'E&xit Application');
        $menu->Append( $m_item );
        EVT_MENU( $taskbar, $m_item,
            sub {
                my($this, $event) = @_;
                my $newevent = Wx::CommandEvent->new($EVT_TASKBAREXIT_ID);
                wxTheApp->AddPendingEvent($newevent);
            }
        );
        $taskbar->PopupMenu($menu);
    });
    
    $self->{taskbar}->SetIcon( Wx::GetWxPerlIcon(), 'TaskBarIconTest' );
}

sub destroy_taskbar {
    my $self = shift;
    if( $self->{taskbar} ) {
        $self->{taskbar}->RemoveIcon;
        $self->{taskbar}->Destroy;
        $self->{taskbar} = undef;
    }
}

#-------------------------------------------

package main;

#-------------------------------------------

my $app = TaskBarIconTest::App->new;
$app->MainLoop;


1;

Reply via email to