Forum > Linux
SendKeys Alernative for Linux
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