Forum > Linux

SendKeys Alernative for Linux

(1/3) > >>

pixelink:
I have am planning to move to Linux OS within a year or two.
So, as I prepare to do so I am beginning to remake some of my windows apps (made in VS studio and Laz) to be Linux compatible
However, I do have an app that uses the Windows Sendkeys functionality that performs "sendkeys" by sending text or OS commands to other applications on Windows.

I am wondering.... is there an equivalent function in Laz (Free Pascal) that I can do something similar to SendKeys on other external programs?
If not, what about a 3rd party package or something similar?

Thanks for any suggestion!

Handoko:
I haven't tried, maybe MouseAndKeyInput unit is what you need. But it is under GPL license, which means you can't use it for closed-sourced projects.

https://wiki.freepascal.org/MouseAndKeyInput

Thaddy:
I found several examples:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit inputsimulator;{$mode objfpc}{$linklib C}     {$linklib X11}   // unit keysym contains the key codes, part of X11 package.interface uses  X, Xlib, Xutil, keysym;  procedure Simulate_KeyPress(keySym: cardinal; shiftState: boolean = false);procedure Simulate_Mouse_Click(x, y: integer; button: integer = 1);procedure Simulate_Mouse_move(x, y: integer); implementation procedure Simulate_KeyPress(keySym: cardinal; shiftState: boolean = false);var  display: PDisplay;  event: TXKeyEvent;  keyCode: TKeyCode;begin  display := XOpenDisplay(nil);  if display = nil then Exit;    keyCode := XKeysymToKeycode(display, keySym);    event.display := display;  event.window := XDefaultRootWindow(display);  event.root := XDefaultRootWindow(display);  event.subwindow := None;  event.time := CurrentTime;  event.x := 1;  event.y := 1;  event.x_root := 1;  event.y_root := 1;  event.same_screen := 1;  event.keycode := keyCode;  event.state := 0;    if shiftState then    event.state := event.state or ShiftMask;    // Key press  event._type := KeyPress;  XSendEvent(display, XDefaultRootWindow(display), 1, KeyPressMask, @event);    // Small delay (optional)  // Sleep(10);    // Key release  event._type := KeyRelease;  XSendEvent(display, XDefaultRootWindow(display), 1, KeyReleaseMask, @event);    XFlush(display);  XCloseDisplay(display);end; procedure Simulate_Mouse_Click(x, y: integer; button: integer = 1);var  display: PDisplay;  event: TXButtonEvent;begin  display := XOpenDisplay(nil);  if display = nil then Exit;    // Move mouse to position  XWarpPointer(display, None, XDefaultRootWindow(display), 0, 0, 0, 0, x, y);  XFlush(display);    // Set up event  event.display := display;  event.window := XDefaultRootWindow(display);  event.root := XDefaultRootWindow(display);  event.subwindow := None;  event.time := CurrentTime;  event.x := x;  event.y := y;  event.x_root := x;  event.y_root := y;  event.same_screen := 1;  event.state := 0;  event.button := button;    // Press  event._type := ButtonPress;  XSendEvent(display, XDefaultRootWindow(display), 1, ButtonPressMask, @event);  XFlush(display);    // Release  event._type := ButtonRelease;  XSendEvent(display, XDefaultRootWindow(display), 1, ButtonReleaseMask, @event);  XFlush(display);    XCloseDisplay(display);end; procedure Simulate_Mouse_move(x, y: integer);var  display: PDisplay;begin  display := XOpenDisplay(nil);  if display = nil then Exit;    XWarpPointer(display, None, XDefaultRootWindow(display), 0, 0, 0, 0, x, y);  XFlush(display);  XCloseDisplay(display);end; end. Depends on X, not tested for Wayland, but XWayland works.

You can also use xdotool, which works like this:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure SimulateWithXdotool(command: string);begin  ExecuteProcess('/usr/bin/xdotool', command);end; // Usage examples:// SimulateWithXdotool('key a');           // Press 'a'// SimulateWithXdotool('key Ctrl+c');      // Press Ctrl+C// SimulateWithXdotool('mousemove 100 100'); // Move mouse// SimulateWithXdotool('click 1');         // Left clickNeeds xdotool installed: apt-get install xdotool

I have more examples, but these need root priviliges.

Thaddy:
Side note:
Does anybody know why I could not post my code without using underscores: the original code did not use underscores, but I get this:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure Simula]"]>BlockeduseClick(x, y: integer; button: integer = 1);procedure Simula]"]>BlockeduseMove(x, y: integer);So I had to add the underscores. Rather irritating...There should not be a security risk, because the code is contained in the codeblock.
Anyway, the inputsimulator unit works, but note some key combinations can be reserved. (also the case with sendkeys)

MarkMLl:
At a somewhat lower level there's the events API https://www.kernel.org/doc/html/v4.18/input/event-codes.html and also see the evtest program: note that this is specifically input device codes, rather than "events" as in interrupts etc.

What I don't know is whether it's possible to send events to a specific process (identified by PIC) or window (identified at the widget set level).

MarkMLl

Navigation

[0] Message Index

[#] Next page

Go to full version