File Coverage

blib/lib/Mac/Apps/Launch.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Mac::Apps::Launch;
2             require 5.004;
3 1     1   29652 use Exporter;
  1         2  
  1         67  
4 1     1   6 use strict;
  1         3  
  1         44  
5 1     1   6 use vars qw($VERSION @ISA @EXPORT);
  1         8  
  1         95  
6 1     1   765 use Mac::Processes;
  0            
  0            
7             use Mac::MoreFiles;
8             use Mac::AppleEvents;
9             #-----------------------------------------------------------------
10             $VERSION = '1.93';
11             @ISA = 'Exporter';
12             @EXPORT = qw(
13             LaunchSpecs LaunchApps QuitApps QuitAllApps IsRunning
14             Show Hide SetFront
15             );
16             #-----------------------------------------------------------------
17             sub _showhide {
18             my($tf, $app, $bool) = @_;
19             my $err = 0;
20             if (!$bool) {
21             foreach my $psn (keys %Process) {
22             if ($Process{$psn}->processSignature eq $app) {
23             $app = $Process{$psn}->processName;
24             last;
25             }
26             }
27             }
28              
29             my $e = AEBuildAppleEvent(qw/core setd sign MACS/, 0, 0,
30             q"'----': obj {form:prop, want:type(prop), seld:type(pvis), from:" .
31             q"obj {form:name, want:type(pcap), seld:TEXT(@), from:'null'()}}," .
32             "data:'$tf'", $app);
33             $err ||= $^E unless $e;
34              
35             my $r = AESend($e, kAEWaitReply);
36             $err ||= $^E unless $r;
37              
38             if ($r && (my $error = AEGetParamDesc($r, 'errn'))) {
39             $err ||= $error->get;
40             AEDisposeDesc $error;
41             }
42             AEDisposeDesc $e if $e;
43             AEDisposeDesc $r if $r;
44             $^E = $err;
45             return !$err;
46             }
47             #-----------------------------------------------------------------
48             sub Show { _showhide('true', @_) }
49             sub Hide { _showhide('fals', @_) }
50             #-----------------------------------------------------------------
51             sub SetFront {
52             my($address, $is_path) = _get_address(@_);
53             for my $psn (keys %Process) {
54             unless ($Process{$psn}) {
55             # warn "$address:$is_path:$psn";
56             next;
57             }
58             next unless $is_path
59             ? $Process{$psn}->processAppSpec =~ /^\Q$address\E/
60             : $Process{$psn}->processSignature eq $address;
61             SetFrontProcess($psn);
62             return 1;
63             }
64             return;
65             }
66             #-----------------------------------------------------------------
67             sub QuitAllApps {
68             my $keepapps;
69             $keepapps = 'McPL' if $^O eq 'MacOS';
70             for (@_) { $keepapps .= "|\Q$_\E" }
71             my $APPL = unpack 'L*', 'APPL';
72              
73             my @apps;
74             for my $psn (keys %Process) {
75             my $proc = $Process{$psn};
76             next unless $proc;
77             my $sig = $proc->processSignature;
78             next if $sig =~ /$keepapps/; # apps to keep running
79             push @apps, $sig if $proc->processType == $APPL;
80             }
81              
82             QuitApps(@apps);
83             }
84             #-----------------------------------------------------------------
85             sub QuitApps {
86             my @apps = @_;
87             my $err = 0;
88             foreach (@apps) {
89             my $e = AEBuildAppleEvent(
90             'aevt', 'quit', typeApplSignature, $_,
91             kAutoGenerateReturnID, kAnyTransactionID, ''
92             );
93             $err ||= $^E unless $e;
94              
95             my $r = AESend($e, kAEWaitReply);
96             $err ||= $^E unless $r;
97              
98             AEDisposeDesc $e if $e;
99             AEDisposeDesc $r if $r;
100             }
101             $^E = $err;
102             return !$err;
103             }
104             #-----------------------------------------------------------------
105             sub LaunchApps {
106             my $err = 0;
107             my @apps = ref $_[0] eq 'ARRAY' ? @{$_[0]} : $_[0];
108             my($switch, $specs, %open);
109              
110             $specs = 1 if (caller(1))[3] &&
111             (caller(1))[3] eq __PACKAGE__ . "::LaunchSpecs";
112              
113             if ($_[1] && $_[1] == 1) {
114             $switch = launchContinue | launchNoFileFlags;
115             } else {
116             $switch = launchContinue | launchNoFileFlags | launchDontSwitch;
117             }
118              
119             for my $n (keys %Process) {
120             my $i = $Process{$n};
121             next unless $i;
122             $open{$i->processSignature} = $i->processAppSpec;
123             }
124              
125             foreach (@apps) {
126             if ($specs) {
127             _launch($_, $switch) or $err ||= $^E;
128             } elsif ($Application{$_}) {
129             my $app_spec = exists $open{$_} ? $open{$_} : $Application{$_};
130             _launch($app_spec, $switch) or $err ||= $^E;
131             } else {
132             $err ||= -5012; # "missing comment/APPL entry"
133             }
134             }
135             $^E = $err;
136             return !$err;
137             }
138             #-----------------------------------------------------------------
139             sub LaunchSpecs { LaunchApps(@_) }
140             #-----------------------------------------------------------------
141             sub _launch {
142             my($app_spec, $switch) = @_;
143             return unless -e $app_spec;
144             my $Launch = new LaunchParam(
145             launchControlFlags => $switch,
146             launchAppSpec => $app_spec,
147             );
148             LaunchApplication($Launch);
149             }
150             #-----------------------------------------------------------------
151             sub IsRunning {
152             my($address, $is_path) = _get_address(@_);
153             for my $psn (keys %Process) {
154             unless ($Process{$psn}) {
155             # warn "$address:$is_path:$psn";
156             next;
157             }
158             return $psn if $is_path
159             ? $Process{$psn}->processAppSpec =~ /^\Q$address\E/
160             : $Process{$psn}->processSignature eq $address;
161             }
162             return;
163             }
164             #-----------------------------------------------------------------
165             sub _get_address {
166             my($address, $is_path) = @_;
167             unless ($is_path) {
168             if (length($address) == 4) {
169             $is_path = 0;
170             } elsif ($address =~ /^(?:\S+\.)+\S+$/) {
171             # try to assume is bundle ID
172             my $path = LSFindApplicationForInfo('', $address);
173             $address = $path if $path;
174             $is_path = 1;
175             } else { # fall back to path ...
176             $is_path = 1;
177             }
178             }
179              
180             return($address, $is_path);
181             }
182              
183             1;
184              
185             __END__