#!/bin/env perl
use strict;
use warnings;
use utf8;
use open qw(:utf8 :std);
use Gtk3 -init;
use POSIX ':sys_wait_h';

my $window = Gtk3::Window->new('toplevel');
$window->set( title => 'Spinner Test', window_position => 'center' );
$window->signal_connect( delete_event => sub { Gtk3->main_quit } );

my $start_button = Gtk3::Button->new_with_mnemonic('_Start Spinner');
my $stop_button  = Gtk3::Button->new_with_mnemonic('S_top Spinners');
my $spinners_box = Gtk3::HBox->new;

my $grid = Gtk3::Grid->new();
$grid->attach( $start_button, 1, 1, 1, 1 );
$grid->attach( $stop_button,  1, 2, 2, 1 );
$grid->attach( $spinners_box, 1, 3, 3, 1 );
$window->add($grid);

my %workers;

$SIG{CHLD} = sub {
    local( $!, $? );
    while( ( my $pid = waitpid( -1, WNOHANG ) ) > 0 ) {
        $workers{$pid}->destroy if $workers{$pid};
        delete $workers{$pid};
        my $exit_code = $? >> 8;
        print "job $pid ended ($exit_code).\n";
    }
};

$stop_button->signal_connect_after( clicked => sub { kill 'INT', keys %workers } );

$start_button->signal_connect_after(
    clicked => sub {
        my $pid = fork;
        die 'fork failed!' if !defined $pid;
        if($pid) {  # parent
            $spinners_box->add( $workers{$pid} = Gtk3::Spinner->new );
            $workers{$pid}->set_tooltip_text($pid);
            $workers{$pid}->show;
            $workers{$pid}->start;
            return;
        }
        else {      # child
            local $SIG{INT} = sub { print "[$$] job interrupted!\n"; exit 255; };
            print "[$$] working…\n";
            sleep 3;
            print "[$$] job done.\n";
            exit 0;
        }
    } );

$window->show_all;
Gtk3->main();
