C/C# Mono в Unix/Linux, взаимодействующий с X11: как я могу переопределить, чтобы XEvent.send_event всегда было ложным при использовании XSendEvent?
Как видно из заголовка, я хотел бы использовать функцию Xlib XSendEvent для имитации "реального" ввода с помощью мыши (вход IE не помечен как send_event = true). Мое приложение написано на C#, но я не боюсь писать библиотеку C и взаимодействовать с ней в моем оригинальном приложении.
Вот что я не ищу:
- XTestFakeButtonEvent
- xdotool
- Пишу
/dev/psaux
" или же "/dev/input/mice
" или же "/dev/input/eventX
"
Вот почему я не ищу вышеупомянутые "решения":
XTestFakeButtonEvent
не позволяет мне указывать координаты X/Y или заголовок окна. Последнее не является для меня проблемой, так как я могу это компенсировать, проверив окно с фокусом ввода перед отправкой ввода мышью. Первое, однако, представляет собой еще большую проблему. Я знаю о XTestFakeMotionEvent и XTestFakeRelativeMotionEvent, но проблема возникает, когда они должны быть отправлены отдельно от исходного XButtonEvent, когда бывают случаи, когда я предпочитаю, чтобы они отправлялись как одно, а не как два отдельных события. Обычно мне было бы все равно, если бы они были отправлены как два отдельных события, но я боюсь, что некоторые приложения делают. Плюс есть дополнительное преимущество более чистой реализации.xdotool
не страдает от тех же проблем, что иXTestFakeButtonEvent
но все же есть две проблемы:Мне не нравится запускать внешние программы командной строки из моего приложения, потому что это неуклюжая реализация.
Я не люблю полагаться на предустановленную такую программу. "Подожди, что? Но разве ты не полагаешься на предустановленный пакет расширения XTest?" Ну да, но вы также должны принять во внимание тот факт, что мне также требуется "
libX11-dev
"Пакет должен быть установлен до того, как приложение будет запущено из-за того, что я взаимодействую с"libX11.so ". Я думаю, что для меня более разумно потребовать два" официальных "пакета Xlib, чем один странный инструмент Xlib.
Запись необработанного ввода с помощью мыши на одно из вышеупомянутых устройств не подойдет, как вы уже догадались, еще две причины.;)
Боюсь, что запись на устройство вызовет у меня проблемы из-за одной очень специфической функциональности в моем приложении. Иногда мне нужно проверять текущее глобальное состояние мыши перед отправкой ввода мышью. Теперь это создает немного загадки. Если я отправлю какой-либо ввод через XSendEvent, то мне нужно будет использовать какую-то библиотеку, которая взаимодействует на более низком уровне, чем Xlib, чтобы получить глобальное состояние мыши, чтобы я не обнаружил ввод, который я уже отправлено, поэтому создается бесконечно повторяющаяся петля обратной связи. Если я напишу на устройство, конечно, оно создаст "реальный" ввод, но это также будет означать, что я не могу легко расшифровать свой ввод от ввода мыши, создавая бесконечный цикл обратной связи. В действительности эта ситуация намного сложнее, чем я могу реально реально объяснить, но это лучший способ, который я знаю, без публикации всего моего частного источника.
Иногда запись на устройство требует
sudo
разрешения. Я не хочу, чтобы мое приложение запускалось как sudoer.
Если вы все еще читаете это, вот что я попробовал:
- Практически все вышеперечисленные вещи, которые я не искал.
- Оборачивание функции 'XSendEvent' в разделяемой библиотеке C с использованием следующих методов: http://samanbarghi.com/blog/2014/09/05/how-to-wrap-a-system-call-libc-function-in-linux/. Причина, по которой это не сработало, заключается в том, что метод 1("LD_PRELOAD") требует от вас использования "LD_PRELOAD" перед запуском моего приложения, которое на самом деле не жизнеспособно (что я собираюсь сделать, попросите всех запустить мое приложение с помощью команды параметр -line?) Метод 2('ld --wrap=symbol'), если я правильно понимаю, потребовал бы от меня связать мою программу с общей библиотекой C, которую я написал, что невозможно увидеть как мой Основным приложением является все C#. Даже если бы я мог заставить их работать, это все равно не имело бы значения, поскольку, кажется, это не работает, когда я сначала вызываю реальную функцию, а затем устанавливаю:
send_event = False;
прежде чем вернуться из упакованной функции. Так что этот был глупым. - Оборачивая XNextEvent в разделяемой библиотеке C ( http://www.semicomplete.com/blog/tags/xsendevent), вызывая реальную функцию, затем выполните: 'send_event = False;' прежде чем вернуться из функции упаковки. Но, так как это
LD_PRELOAD
Решение требует, чтобы любое приложение, которое я собирался отправлять мышью, запускалось с установленной переменной окружения. Предположительно это работает, но я думаю, что это последнее средство. Что если кто-то запустит мое приложение в первый раз, ожидая, что оно будет работать с любым открытым приложением, но это не так, потому что я установил переменную среды при первом запуске и не вступит в силу, пока все приложения не будут сброшены? Что произойдет, если кто-то удалит переменную окружения из конфигурации bash? Что если они не используют конфиги bash? Что если они используют другой терминал? Я должен поддержать их всех? Это кажется неуклюжим, как весь ад. - Возможно, моя лучшая и единственная надежда еще, писать свой собственный новый
XSendEvent
функция в C, которая напрямую взаимодействует с Xlib для ручной настройкиsend_event = False;
и завернуть его в общую библиотеку, чтобы я мог дальше взаимодействовать с ним через C#. Я пытался несколько раз переписатьXSendEvent
используя следующий источник в качестве моей ссылки: https://github.com/mirror/libX11/blob/master/src/SendEvent.c. Но даже после поиска по всему исходному коду Xlib я даже не могу понять, что именно устанавливает "send_event
переменная или как я могу остановить это от моего модифицированногоXSendEvent
функция. Поверьте мне, я попытался просто установить его внутри функции. Неважно, где я его разместил, это не имело значения. Я могу только заключить, что это устанавливается где-то еще полностью послеXSendEvent
выполнен. Я могу ошибаться в этом, и я бы хотел быть. Я искал весь источник и нашел кусочки, гдеsend_event
был установлен, но он даже не был вызванXSendEvent
непосредственно.
Послушайте, если вы не сошли с ума, читая это, тогда я аплодирую вам, потому что чуть не сошел с ума, пытаясь найти решение. На самом деле я никогда не задаю вопрос о Stackru, если не чувствую, что больше некуда обратиться. Я искал, искал и искал. Я старался изо всех сил, чтобы проявить должную осмотрительность, но, очевидно, потерпел неудачу Может быть, есть кто-то, кто прочитал все это и нашел какое-то оригинальное решение. Если нет, я буду продолжать искать. Я надеюсь, что это было наглядно и максимально полезно. Большое спасибо за ваше время.