Перейти к содержанию
Fire Monkey от А до Я
  • 0

Глобальный Hook в OSX


dnekrasov

Вопрос

Создаю глобальный hook на несколько событий:

{$IFDEF MACOS}
var
  EvtTap: CFMachPortRef;
  RunLoopSource: CFRunLoopSourceRef;
{$ENDIF}
...
procedure CreateGlobalHook;
{$IFDEF MACOS} 
var 
  EvtMask: UInt64; 
{$ENDIF} 
begin 
{$IFDEF MACOS} 
  if EvtTap = nil then
  begin 
    EvtMask := (1 shl kCGEventKeyDown) or (1 shl kCGEventFlagsChanged) or (1 shl kCGEventLeftMouseUp); 
    EvtTap := CGEventTapCreate(kCGAnnotatedSessionEventTap, kCGTailAppendEventTap, kCGEventTapOptionListenOnly, 
    EvtMask, @EventTapHandler, nil); 
    RunLoopSource := CFMachPortCreateRunLoopSource(kCFAllocatorDefault, EvtTap, 0); 
    CFRunLoopAddSource(CFRunLoopGetCurrent, RunLoopSource, kCFRunLoopCommonModes); 
  end; 

  CGEventTapEnable(EvtTap, 1);
{$ENDIF} 
end;

function EventTapHandler(proxy: CGEventTapProxy; type_: CGEventType; event: CGEventRef; refcon: Pointer): CGEventRef; cdecl;
{$IFDEF MACOS}
var
  iKey: Integer;
  iType: Integer;
{$ENDIF}
begin
{$IFDEF MACOS}
  Result := event;

  iType := CGEventGetType(event);
  iKey := CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);

  case iType of
    kCGEventFlagsChanged: ...;
    kCGEventLeftMouseUp: ...;
    kCGEventKeyDown: ...;
  end;
{$ENDIF}
end;

При обработке события возникает проблема: приходят все события кроме kCGEventKeyDown

В документации нашел, что kCGEventKeyDown и kCGEventKeyUp приходят только в том случае если приложение запущено от root-а или внесено в список "System Preferences->Security & Privacy->Privacy->Accessibility"

 

Может кто знает как мне программно получить доступ к этим событиям?

Изменено пользователем dnekrasov
Ссылка на комментарий

Рекомендуемые сообщения

  • 1

Пока нашел только такой выход:

  Создаю инсталляшку с помошью Packages (http://s.sudre.free.fr/Software/Packages/about.html)

  При завершении установки выполняю скрипт

#!/bin/sh
touch /private/var/db/.AccessibilityAPIEnabled && sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" "INSERT or REPLACE INTO access (service, client, client_type, allowed, prompt_count) VALUES ('kTCCServiceAccessibility', 'com.CompanyName.AppName', 0, 1, 0);"

После этого все работает!

Ссылка на комментарий
  • 0

Отлавливать события kCGEventKeyDown необходимо было только ради реализации глобальных хоткеев. Их сделал другим способом.

Так что тему можно закрывать.

Ссылка на комментарий
Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...