line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package # Hide from the CPAN indexer |
2
|
|
|
|
|
|
|
POE::XUL::Session; |
3
|
|
|
|
|
|
|
# $Id$ |
4
|
|
|
|
|
|
|
# Copyright Philip Gwyn 2007-2010. All rights reserved. |
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
32
|
|
7
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
21
|
|
8
|
1
|
|
|
1
|
|
4
|
use Carp; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
48
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '0.0601'; |
11
|
|
|
|
|
|
|
|
12
|
1
|
|
|
1
|
|
4
|
use POE; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
5
|
|
13
|
1
|
|
|
1
|
|
237
|
use base qw(POE::Session); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
92
|
|
14
|
|
|
|
|
|
|
|
15
|
1
|
|
|
1
|
|
4
|
use POE::XUL::Logging; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
50
|
|
16
|
|
|
|
|
|
|
|
17
|
1
|
|
|
1
|
|
4
|
use POSIX qw( ENOSYS ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
18
|
1
|
|
|
1
|
|
46
|
use Carp; |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
33
|
|
19
|
|
|
|
|
|
|
|
20
|
1
|
|
|
1
|
|
4
|
use constant DEBUG => 0; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
644
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
################################################################ |
23
|
|
|
|
|
|
|
my %SELVES; |
24
|
|
|
|
|
|
|
sub create |
25
|
|
|
|
|
|
|
{ |
26
|
0
|
|
|
0
|
1
|
|
my( $package, $application ) = @_; |
27
|
|
|
|
|
|
|
|
28
|
0
|
|
|
|
|
|
return $package->SUPER::create( |
29
|
|
|
|
|
|
|
inline_states => { |
30
|
|
|
|
|
|
|
_start => \&_never, |
31
|
|
|
|
|
|
|
_stop => \&_never, |
32
|
|
|
|
|
|
|
}, |
33
|
|
|
|
|
|
|
args => [ $application ] |
34
|
|
|
|
|
|
|
); |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
|
37
|
0
|
|
|
0
|
|
|
sub _never { confess "Never invoke me" } |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub _get_self |
41
|
|
|
|
|
|
|
{ |
42
|
0
|
|
|
0
|
|
|
my( $session ) = @_; |
43
|
0
|
0
|
|
|
|
|
return $session unless $session->isa( 'POE::Session' ); |
44
|
0
|
|
|
|
|
|
return $SELVES{ $session->ID }; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
################################################################ |
48
|
|
|
|
|
|
|
sub _invoke_state { |
49
|
0
|
|
|
0
|
|
|
my( $session, $source_session, $state, $etc, $file, $line, |
50
|
|
|
|
|
|
|
$source_state ) = @_; |
51
|
|
|
|
|
|
|
|
52
|
0
|
0
|
|
|
|
|
if( $state eq '_stop' ) { |
|
|
0
|
|
|
|
|
|
53
|
0
|
|
|
|
|
|
delete $SELVES{ $session->ID }; |
54
|
0
|
|
|
|
|
|
DEBUG and xwarn "_stop"; |
55
|
0
|
|
|
|
|
|
return; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
elsif( $state eq '_start' ) { |
58
|
0
|
|
|
|
|
|
my $self = $SELVES{ $session->ID } = |
59
|
|
|
|
|
|
|
POE::XUL::Session::Delegate->new( $session, $etc->[0] ); |
60
|
0
|
|
|
|
|
|
return $self->_start(); |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
0
|
|
|
|
|
|
my $self = $session->_get_self; |
64
|
|
|
|
|
|
|
|
65
|
0
|
|
|
|
|
|
DEBUG and xwarn "Invoking $state\n"; |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
|
68
|
0
|
0
|
|
|
|
|
if ($session->[POE::Session::SE_OPTIONS]->{+POE::Session::OPT_TRACE}) { |
69
|
0
|
|
|
|
|
|
xwarn( $POE::Kernel::poe_kernel->ID_session_to_id($session), |
70
|
|
|
|
|
|
|
" -> $state (from $file at $line)\n" |
71
|
|
|
|
|
|
|
); |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
0
|
|
|
|
|
|
my $handler = $session->[POE::Session::SE_STATES]->{$state}; |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
# The desired destination state doesn't exist in this session. |
77
|
|
|
|
|
|
|
# Attempt to redirect the state transition to _default. |
78
|
0
|
0
|
|
|
|
|
unless ( $handler ) { |
79
|
0
|
|
|
|
|
|
$handler = $session->[POE::Session::SE_STATES]->{+POE::Session::EN_DEFAULT}; |
80
|
0
|
0
|
|
|
|
|
unless( $handler ) { |
81
|
0
|
|
|
|
|
|
$! = ENOSYS; |
82
|
0
|
0
|
|
|
|
|
if ($session->[POE::Session::SE_OPTIONS]->{+POE::Session::OPT_DEFAULT}) { |
83
|
0
|
|
|
|
|
|
xwarn( "a '$state' state was sent from $file at $line to session ", |
84
|
|
|
|
|
|
|
$POE::Kernel::poe_kernel->ID_session_to_id($session), |
85
|
|
|
|
|
|
|
", but session ", |
86
|
|
|
|
|
|
|
$POE::Kernel::poe_kernel->ID_session_to_id($session), |
87
|
|
|
|
|
|
|
" has neither that state nor a _default state to handle it\n" |
88
|
|
|
|
|
|
|
); |
89
|
|
|
|
|
|
|
} |
90
|
0
|
|
|
|
|
|
DEBUG and xwarn "No handler for $state"; |
91
|
0
|
|
|
|
|
|
return undef; |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
0
|
|
|
|
|
|
local $POE::XUL::Application::window = $self->{main_window}; |
96
|
0
|
|
|
|
|
|
local $POE::XUL::Application::server = $self; |
97
|
0
|
|
|
|
|
|
local $POE::XUL::Node::CM = $self->{CM}; |
98
|
0
|
|
|
|
|
|
local $self->{source_session} = $source_session; |
99
|
0
|
|
|
|
|
|
local $self->{source_state} = $source_state; |
100
|
0
|
|
|
|
|
|
local $self->{source_file} = $file; |
101
|
0
|
|
|
|
|
|
local $self->{source_line} = $line; |
102
|
0
|
|
|
|
|
|
local $self->{current_state} = $state; |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# warn "P::X::App:window=$POE::XUL::Application::window"; |
105
|
|
|
|
|
|
|
# warn "M::App::window=".My::Application::window(); |
106
|
|
|
|
|
|
|
|
107
|
0
|
|
|
|
|
|
my $wa = wantarray; |
108
|
|
|
|
|
|
|
# DEBUG and xwarn "${state}'s handler is $handler, wantarray=", (defined $wa ? $wa : '' ); |
109
|
|
|
|
|
|
|
|
110
|
0
|
|
|
|
|
|
my( $OK, @ret ); |
111
|
0
|
0
|
|
|
|
|
if( $wa ) { |
112
|
0
|
|
|
|
|
|
eval { |
113
|
0
|
0
|
|
|
|
|
if( 'CODE' eq ref $handler ) { |
114
|
0
|
|
|
|
|
|
@ret = $handler->( @$etc ); |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
else { |
117
|
0
|
|
|
|
|
|
my( $object, $method ) = @$handler; |
118
|
0
|
|
|
|
|
|
@ret = $object->$method( @$etc ); |
119
|
|
|
|
|
|
|
} |
120
|
0
|
|
|
|
|
|
$OK = 1; |
121
|
|
|
|
|
|
|
}; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
else { |
124
|
0
|
|
|
|
|
|
my $ret; |
125
|
0
|
|
|
|
|
|
eval { |
126
|
0
|
0
|
|
|
|
|
if( 'CODE' eq ref $handler ) { |
127
|
0
|
|
|
|
|
|
$ret[0] = $handler->( @$etc ); |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
else { |
130
|
0
|
|
|
|
|
|
my( $object, $method ) = @$handler; |
131
|
0
|
|
|
|
|
|
$ret[0] = $object->$method( @$etc ); |
132
|
|
|
|
|
|
|
} |
133
|
0
|
|
|
|
|
|
$OK = 1; |
134
|
|
|
|
|
|
|
}; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
0
|
0
|
|
|
|
|
if( $OK ) { |
138
|
0
|
0
|
|
|
|
|
return @ret if wantarray; |
139
|
0
|
|
|
|
|
|
return $ret[0]; |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
0
|
|
|
|
|
|
$self->event_error( "PERL ERROR: $@" ); |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
############################################################################# |
146
|
|
|
|
|
|
|
package POE::XUL::Session::Delegate; |
147
|
|
|
|
|
|
|
|
148
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
18
|
|
149
|
1
|
|
|
1
|
|
3
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
38
|
|
150
|
|
|
|
|
|
|
|
151
|
1
|
|
|
1
|
|
6
|
use POE::Kernel; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
7
|
|
152
|
1
|
|
|
1
|
|
44
|
use POE::XUL::Logging; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
51
|
|
153
|
|
|
|
|
|
|
|
154
|
1
|
|
|
1
|
|
3
|
use constant DEBUG => 0; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
46
|
|
155
|
1
|
|
|
1
|
|
3
|
use Carp; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
40
|
|
156
|
1
|
|
|
1
|
|
1369
|
use Devel::Peek; |
|
1
|
|
|
|
|
438
|
|
|
1
|
|
|
|
|
5
|
|
157
|
1
|
|
|
1
|
|
100
|
use Data::Dumper; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
329
|
|
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
################################################################ |
160
|
|
|
|
|
|
|
sub new |
161
|
|
|
|
|
|
|
{ |
162
|
0
|
|
|
0
|
|
|
my( $package, $session, $application ) = @_; |
163
|
0
|
|
|
|
|
|
return bless { |
164
|
|
|
|
|
|
|
session => $session->ID, |
165
|
|
|
|
|
|
|
application => $application |
166
|
|
|
|
|
|
|
}, $package; |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
################################################################ |
170
|
|
|
|
|
|
|
sub _start |
171
|
|
|
|
|
|
|
{ |
172
|
0
|
|
|
0
|
|
|
my( $self ) = @_; |
173
|
0
|
|
|
|
|
|
DEBUG and xwarn "$$: _start ", $self->SID; |
174
|
0
|
|
|
|
|
|
$poe_kernel->alias_set( $self->SID ); |
175
|
0
|
|
|
|
|
|
$poe_kernel->alias_set( $self ); |
176
|
0
|
|
|
|
|
|
$poe_kernel->state( boot => $self ); |
177
|
0
|
|
|
|
|
|
$poe_kernel->state( timeout => $self ); |
178
|
0
|
|
|
|
|
|
$poe_kernel->state( shutdown => $self ); |
179
|
0
|
|
|
|
|
|
$poe_kernel->state( connect => $self ); |
180
|
0
|
|
|
|
|
|
$poe_kernel->state( disconnect => $self ); |
181
|
0
|
|
|
|
|
|
return; |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
################################################################ |
185
|
|
|
|
|
|
|
sub ID |
186
|
|
|
|
|
|
|
{ |
187
|
0
|
|
|
0
|
|
|
my( $self ) = @_; |
188
|
0
|
|
|
|
|
|
return $self->{session}; |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub SID |
192
|
|
|
|
|
|
|
{ |
193
|
0
|
|
|
0
|
|
|
my( $self ) = @_; |
194
|
0
|
|
|
|
|
|
return $self->{application}->SID; |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub session |
198
|
|
|
|
|
|
|
{ |
199
|
0
|
|
|
0
|
|
|
my( $self ) = @_; |
200
|
0
|
0
|
|
|
|
|
return unless $self->{session}; |
201
|
0
|
|
|
|
|
|
return $poe_kernel->ID_id_to_session( $self->{session} ); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
0
|
|
|
0
|
|
|
sub sender_file { $_[0]->{source_file} } |
205
|
0
|
|
|
0
|
|
|
sub sender_line { $_[0]->{source_line} } |
206
|
0
|
|
|
0
|
|
|
sub sender_state { $_[0]->{source_state} } |
207
|
0
|
|
|
0
|
|
|
sub sender_session { $_[0]->{source_session} } |
208
|
0
|
|
|
0
|
|
|
sub current_state { $_[0]->{current_state} } |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
################################################################ |
211
|
|
|
|
|
|
|
# Initial boot request |
212
|
|
|
|
|
|
|
sub boot |
213
|
|
|
|
|
|
|
{ |
214
|
0
|
|
|
0
|
|
|
my( $self, $event ) = @_; |
215
|
0
|
|
|
|
|
|
$self->{name} = $event->app; |
216
|
0
|
|
|
|
|
|
$self->{CM} = $event->CM; |
217
|
1
|
|
|
1
|
|
4
|
use Data::Dumper; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
997
|
|
218
|
0
|
0
|
|
|
|
|
$self->{name} or die Dumper $event; |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# we didn't have a CM until now, so _invoke_state didn't set it |
221
|
0
|
|
|
|
|
|
local $POE::XUL::Node::CM = $self->{CM}; |
222
|
|
|
|
|
|
|
|
223
|
0
|
|
|
|
|
|
xlog "Boot $self->{name}"; |
224
|
|
|
|
|
|
|
|
225
|
0
|
|
|
|
|
|
$self->{application}->boot( $event ); |
226
|
|
|
|
|
|
|
|
227
|
0
|
0
|
|
|
|
|
unless( $self->{booted} ) { |
228
|
0
|
|
|
|
|
|
xlog "Application didn't Boot(), using $self->{name}"; |
229
|
0
|
|
|
|
|
|
POE::XUL::Node::Boot( $self->{name} ); |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
croak "You must create a Window during $self->{SID}/boot" |
233
|
0
|
0
|
|
|
|
|
unless $self->{main_window}; |
234
|
0
|
|
|
|
|
|
$event->handled; |
235
|
0
|
|
|
|
|
|
return; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
################################################################ |
239
|
|
|
|
|
|
|
# POE::XUL::Node::Boot telling us the boot message |
240
|
|
|
|
|
|
|
sub Boot |
241
|
|
|
|
|
|
|
{ |
242
|
0
|
|
|
0
|
|
|
my( $self, $msg ) = @_; |
243
|
0
|
|
|
|
|
|
$self->{booted} = 1; |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
################################################################ |
249
|
|
|
|
|
|
|
## window->open creates a temporary window (TWindow) |
250
|
|
|
|
|
|
|
## It, in turn, tells us so |
251
|
|
|
|
|
|
|
sub attach_subwindow |
252
|
|
|
|
|
|
|
{ |
253
|
0
|
|
|
0
|
|
|
my( $self, $twindow ) = @_; |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
# save the twindow until we get the 'connect' event |
256
|
0
|
|
|
|
|
|
$self->{subwindows}{ $twindow->id } = $twindow; |
257
|
0
|
|
|
|
|
|
return; |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
################################################################ |
262
|
|
|
|
|
|
|
## New sub-window connect request |
263
|
|
|
|
|
|
|
sub connect |
264
|
|
|
|
|
|
|
{ |
265
|
0
|
|
|
0
|
|
|
my( $self, $event ) = @_; |
266
|
0
|
|
|
|
|
|
my $winID = $event->window; |
267
|
0
|
|
|
|
|
|
xlog "Connect $winID"; |
268
|
|
|
|
|
|
|
|
269
|
0
|
|
|
|
|
|
my $twindow = delete $self->{subwindows}{ $winID }; |
270
|
0
|
0
|
|
|
|
|
die "Connect $winID, but we don't have that TWindow." unless $twindow; |
271
|
|
|
|
|
|
|
|
272
|
0
|
|
|
|
|
|
$twindow->create_window(); |
273
|
0
|
|
|
|
|
|
$twindow->dispose(); |
274
|
|
|
|
|
|
|
|
275
|
0
|
|
|
|
|
|
$self->window_call( $event, 'Connect' ); |
276
|
|
|
|
|
|
|
|
277
|
0
|
|
|
|
|
|
$event->handled; |
278
|
0
|
|
|
|
|
|
return; |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
################################################################ |
282
|
|
|
|
|
|
|
## Sub-window disconnect request |
283
|
|
|
|
|
|
|
sub disconnect |
284
|
|
|
|
|
|
|
{ |
285
|
0
|
|
|
0
|
|
|
my( $self, $event ) = @_; |
286
|
0
|
|
|
|
|
|
my $winID = $event->window->id; |
287
|
0
|
|
|
|
|
|
xlog "Disconnect $winID"; |
288
|
|
|
|
|
|
|
|
289
|
0
|
|
|
|
|
|
$self->window_call( $event, 'Disconnect' ); |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
# delete the window, and all sub-elements |
292
|
0
|
|
|
|
|
|
$event->window->dispose; |
293
|
0
|
|
|
|
|
|
$event->set( window => undef ); |
294
|
|
|
|
|
|
|
|
295
|
0
|
|
|
|
|
|
$event->handled; |
296
|
0
|
|
|
|
|
|
return; |
297
|
|
|
|
|
|
|
} |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
################################################################ |
300
|
|
|
|
|
|
|
## Call a handler for a sub-window |
301
|
|
|
|
|
|
|
sub window_call |
302
|
|
|
|
|
|
|
{ |
303
|
0
|
|
|
0
|
|
|
my( $self, $event, $name ) = @_; |
304
|
0
|
|
|
|
|
|
my $listener = $event->window->event( $name ); |
305
|
0
|
0
|
|
|
|
|
if( $listener ) { |
306
|
|
|
|
|
|
|
# it's up to the handler to do ->defer if it needs it |
307
|
0
|
|
|
|
|
|
$event->done( 1 ); |
308
|
0
|
0
|
|
|
|
|
if( ref $listener ) { |
309
|
0
|
|
|
|
|
|
$listener->( $event ); |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
else { |
312
|
0
|
|
|
|
|
|
DEBUG and xwarn "$name -> $listener"; |
313
|
|
|
|
|
|
|
# we don't use ->yield because we want the event to go |
314
|
|
|
|
|
|
|
# through before we return |
315
|
0
|
|
|
|
|
|
$poe_kernel->call( $self->SID, $listener, $event ); |
316
|
|
|
|
|
|
|
} |
317
|
0
|
|
|
|
|
|
return; |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
|
320
|
0
|
|
|
|
|
|
$name = lc $name; |
321
|
0
|
0
|
|
|
|
|
if( $self->{application}->can( $name ) ) { |
322
|
0
|
|
|
|
|
|
DEBUG and xwarn "->$name"; |
323
|
0
|
|
|
|
|
|
$self->{application}->$name( $event ); |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
|
326
|
0
|
|
|
|
|
|
return; |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
################################################################ |
331
|
|
|
|
|
|
|
## Application shutdown (close or timeout) |
332
|
|
|
|
|
|
|
sub shutdown |
333
|
|
|
|
|
|
|
{ |
334
|
0
|
|
|
0
|
|
|
my( $self ) = @_; |
335
|
0
|
|
|
|
|
|
DEBUG and xwarn "Application $self->{name} shutdown"; |
336
|
0
|
0
|
|
|
|
|
if( $self->{application}->can( 'shutdown' ) ) { |
337
|
0
|
|
|
|
|
|
$self->{application}->shutdown(); |
338
|
|
|
|
|
|
|
} |
339
|
0
|
|
|
|
|
|
$poe_kernel->alias_remove( $self ); |
340
|
0
|
|
|
|
|
|
$poe_kernel->alias_remove( $self->SID ); |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
################################################################ |
344
|
|
|
|
|
|
|
## Application timeout |
345
|
|
|
|
|
|
|
sub timeout |
346
|
|
|
|
|
|
|
{ |
347
|
0
|
|
|
0
|
|
|
my( $self ) = @_; |
348
|
0
|
|
|
|
|
|
DEBUG and xwarn "Application $self->{name} timeout"; |
349
|
0
|
0
|
|
|
|
|
if( $self->{application}->can( 'timeout' ) ) { |
350
|
0
|
|
|
|
|
|
$self->{application}->timeout(); |
351
|
|
|
|
|
|
|
} |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
################################################################ |
355
|
|
|
|
|
|
|
## Error from _invoke_state |
356
|
|
|
|
|
|
|
sub event_error |
357
|
|
|
|
|
|
|
{ |
358
|
0
|
|
|
0
|
|
|
my( $self, $msg ) = @_; |
359
|
0
|
|
|
|
|
|
$self->{CM}->wrapped_error( $msg ); |
360
|
|
|
|
|
|
|
} |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
################################################################ |
363
|
|
|
|
|
|
|
## Reflection |
364
|
|
|
|
|
|
|
sub has_handler |
365
|
|
|
|
|
|
|
{ |
366
|
0
|
|
|
0
|
|
|
my( $self, $state ) = @_; |
367
|
0
|
|
|
|
|
|
$! = 0; |
368
|
0
|
|
|
|
|
|
my $handler = $self->session->[POE::Session::SE_STATES]->{$state}; |
369
|
0
|
0
|
|
|
|
|
return 1 if $handler; |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
# The desired destination state doesn't exist in this session. |
372
|
|
|
|
|
|
|
# Attempt to redirect the state transition to _default. |
373
|
0
|
|
|
|
|
|
$handler = $self->session->[POE::Session::SE_STATES]->{+POE::Session::EN_DEFAULT}; |
374
|
0
|
0
|
|
|
|
|
return 1 if $handler; |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
# No dice |
377
|
0
|
|
|
|
|
|
$! = POSIX::ENOSYS(); |
378
|
0
|
|
|
|
|
|
return; |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
################################################################ |
382
|
|
|
|
|
|
|
## POE::XUL::ChangeManager telling us about a new window |
383
|
|
|
|
|
|
|
sub register_window |
384
|
|
|
|
|
|
|
{ |
385
|
0
|
|
|
0
|
|
|
my( $self, $node ) = @_; |
386
|
0
|
0
|
0
|
|
|
|
unless( $self->{main_window} ) { |
|
|
0
|
|
|
|
|
|
387
|
0
|
|
|
|
|
|
$self->{main_window} = $node; |
388
|
0
|
|
|
|
|
|
$POE::XUL::Application::window = $node; |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
elsif( $self->{CM} and $self->{CM}{current_event} ) { |
391
|
0
|
|
|
|
|
|
$self->{CM}{current_event}->window( $node ); |
392
|
0
|
|
|
|
|
|
$self->{CM}{current_event}{window_id} = $node->id; |
393
|
|
|
|
|
|
|
} |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
################################################################ |
397
|
|
|
|
|
|
|
## Create a handler if needs be |
398
|
|
|
|
|
|
|
sub attach_handler |
399
|
|
|
|
|
|
|
{ |
400
|
0
|
|
|
0
|
|
|
my( $self, $node, $name, $listener ) = @_; |
401
|
|
|
|
|
|
|
|
402
|
0
|
|
|
|
|
|
my $app = $self->{application}; |
403
|
|
|
|
|
|
|
|
404
|
0
|
0
|
|
|
|
|
if( ref $listener ) { |
405
|
|
|
|
|
|
|
# CODEREF -> create an event for that coderef |
406
|
0
|
|
|
|
|
|
my $state = join '-', "poe-xul", $name, $node->id; |
407
|
0
|
|
|
|
|
|
$app->createHandler( $state, $listener ); |
408
|
0
|
|
|
|
|
|
return $state; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
# other -> create an event for that event |
412
|
0
|
|
|
|
|
|
my @check = ( $listener ); |
413
|
0
|
0
|
|
|
|
|
if( $node->id ) { |
414
|
0
|
|
|
|
|
|
my $id = $node->id; |
415
|
0
|
|
|
|
|
|
$id =~ s/\W/_/g; |
416
|
0
|
|
|
|
|
|
push @check, join '_', 'xul', $name, $id; |
417
|
|
|
|
|
|
|
} |
418
|
0
|
|
|
|
|
|
push @check, $name; |
419
|
0
|
|
|
|
|
|
DEBUG and xwarn $node->id, ".$name one of ", join ', ', @check; |
420
|
0
|
|
|
|
|
|
foreach my $state ( @check ) { |
421
|
0
|
0
|
|
|
|
|
next unless defined $state; |
422
|
0
|
0
|
|
|
|
|
return $state if $self->has_handler( $state ); # already have one? |
423
|
|
|
|
|
|
|
|
424
|
0
|
0
|
|
|
|
|
next unless $app->can( $state ); # couldn't object handle it? |
425
|
|
|
|
|
|
|
|
426
|
0
|
|
|
|
|
|
DEBUG and xwarn "Creating handler for ", $node->id, ".$name event ($state)"; |
427
|
0
|
|
|
|
|
|
$app->createHandler( $state ); |
428
|
0
|
|
|
|
|
|
return $state; |
429
|
|
|
|
|
|
|
} |
430
|
0
|
0
|
|
|
|
|
if( $listener ) { |
431
|
0
|
|
|
|
|
|
xcarp "Can't handle $name event $listener via package ", ref $app; |
432
|
|
|
|
|
|
|
} |
433
|
|
|
|
|
|
|
else { |
434
|
0
|
|
|
|
|
|
xcarp "Can't handle event $name via package ", ref $app; |
435
|
|
|
|
|
|
|
} |
436
|
0
|
|
|
|
|
|
return; |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
1; |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
__DATA__ |