Как я могу закрыть окно, используя OS-X ScriptingBridge Framework, из Perl? - PullRequest
1 голос
/ 12 апреля 2010

Проблема ...

Поскольку MacPerl больше не поддерживается на 64-битном Perl , я пытаюсь использовать альтернативные платформы для управления Terminal.app.

Я пытаюсь ScriptingBridge , но столкнулся с проблемой передачи перечислимой строки в метод closeSaving с использованием PerlObjCBridge .

Я хочу позвонить:

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.

Попытка решения ...

Я пробовал:

#!/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....

Как видите, все мои предположения о том, как передать перечисленную строку, не удаются.

Перед тем, как ты меня обожжешь ...

  • Я знаю, что мог бы использовать для этого другой язык (ruby, python, cocoa), но для этого потребовался бы перевод остальной части кода.
  • Возможно, я смогу использовать CamelBones , но я не хочу предполагать, что мои пользователи установили его.
  • Я также мог бы использовать платформу NSAppleScript (если предположить, что столкнулся с проблемой поиска идентификаторов вкладки и окна), но мне кажется странным прибегать к нему только для этого одного вызова.

1 Ответ

2 голосов
/ 12 апреля 2010
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 не называет строковые константы; он называет int константы. Каждое из этих имен имеет значение int.

Итак, попробуйте вместо этого указать a или I. Или выполните оба действия: укажите как a, затем распакуйте как I и передайте это число.

...