开发者

How can I close a Window using the OS-X ScriptingBridge framework, from Perl?

开发者 https://www.devze.com 2022-12-26 18:11 出处:网络
Problem... Since MacPerl is no longer supported on 64bit perl, I am trying alter开发者_StackOverflow中文版native frameworks to control Terminal.app.

Problem...

Since MacPerl is no longer supported on 64bit perl, I am trying alter开发者_StackOverflow中文版native frameworks to control Terminal.app.

I am trying the ScriptingBridge, but have run into a problem passing an enumerated string to the closeSaving method using the PerlObjCBridge.

I want to call:

typedef enum {
    TerminalSaveOptionsYes = 'yes ' /* Save the file. */,
    TerminalSaveOptionsNo = 'no  '  /* Do not save the file. */,
    TerminalSaveOptionsAsk = 'ask ' /* Ask the user whether or not to save the file. */
} TerminalSaveOptions;

- (void) closeSaving:(TerminalSaveOptions)saving savingIn:(NSURL *)savingIn;  // Close a document.

Attempted Solution...

I have tried:

#!/usr/bin/perl

use strict;
use warnings;
use Foundation;

# Load the ScriptingBridge framework
NSBundle->bundleWithPath_('/System/Library/Frameworks/ScriptingBridge.framework')->load;
@SBApplication::ISA = qw(PerlObjCBridge);

# Set up scripting bridge for Terminal.app
my $terminal = SBApplication->applicationWithBundleIdentifier_("com.apple.terminal");

# Open a new window, get back the tab
my $tab = $terminal->doScript_in_('exec sleep 60', undef);
warn "Opened tty: ".$tab->tty->UTF8String; # Yes, it is a tab

# Now try to close it

# Simple idea
eval { $tab->closeSaving_savingIn_('no  ', undef) }; warn $@ if $@;

# Try passing a string ref
my $no = 'no  ';
eval { $tab->closeSaving_savingIn_(\$no, undef) }; warn $@ if $@;

# Ok - get a pointer to the string
my $pointer = pack("P4", $no);
eval { $tab->closeSaving_savingIn_($pointer, undef) }; warn $@ if $@;
eval { $tab->closeSaving_savingIn_(\$pointer, undef) }; warn $@ if $@;

# Try a pointer decodes as an int, like PerlObjCBridge uses
my $int_pointer = unpack("L!", $pointer);
eval { $tab->closeSaving_savingIn_($int_pointer,  undef) }; warn $@ if $@;
eval { $tab->closeSaving_savingIn_(\$int_pointer, undef) }; warn $@ if $@;

# Aaarrgghhhh....

As you can see, all my guesses at how to pass the enumerated string fail.

Before you flame me...

  • I know that I could use another language (ruby, python, cocoa) to do this but that would require translating the rest of the code.
  • I might be able to use CamelBones, but I don't want to assume my users have it installed.
  • I could also use the NSAppleScript framework (assuming I went to the trouble of finding the Tab and Window IDs) but it seems odd to have to resort to it for just this one call.


typedef enum {
    TerminalSaveOptionsYes = 'yes ' /* Save the file. */,
    TerminalSaveOptionsNo = 'no  '  /* Do not save the file. */,
    TerminalSaveOptionsAsk = 'ask ' /* Ask the user whether or not to save the file. */
} TerminalSaveOptions;

enum does not name string constants; it names int constants. Each of these names is of an int value.

So, try packing as a or I instead. Or, do both: Pack as a, then unpack as I and pass that number.

0

精彩评论

暂无评论...
验证码 换一张
取 消