Recent

Author Topic: SendKeys Alernative for Linux  (Read 1241 times)

pixelink

  • Hero Member
  • *****
  • Posts: 1269
SendKeys Alernative for Linux
« on: October 29, 2025, 12:40:46 am »
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!
« Last Edit: October 29, 2025, 02:20:46 am by pixelink »
Can't Type - Forgetful - Had Stroke = Forgive this old man!
LAZ 4.2.0 •  VSSTUDIO(.Net) 2022 • Win11 • 32G RAM • Nvida RTX 4070 Ti Super

Handoko

  • Hero Member
  • *****
  • Posts: 5515
  • My goal: build my own game engine using Lazarus
Re: SendKeys Alernative for Linux
« Reply #1 on: October 29, 2025, 04:41:13 am »
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

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: SendKeys Alernative for Linux
« Reply #2 on: October 29, 2025, 06:58:30 am »
I found several examples:
Code: Pascal  [Select][+][-]
  1. unit inputsimulator;
  2. {$mode objfpc}
  3. {$linklib C}    
  4. {$linklib X11}  
  5. // unit keysym contains the key codes, part of X11 package.
  6. interface
  7.  
  8. uses
  9.   X, Xlib, Xutil, keysym;
  10.  
  11.  
  12. procedure Simulate_KeyPress(keySym: cardinal; shiftState: boolean = false);
  13. procedure Simulate_Mouse_Click(x, y: integer; button: integer = 1);
  14. procedure Simulate_Mouse_move(x, y: integer);
  15.  
  16. implementation
  17.  
  18. procedure Simulate_KeyPress(keySym: cardinal; shiftState: boolean = false);
  19. var
  20.   display: PDisplay;
  21.   event: TXKeyEvent;
  22.   keyCode: TKeyCode;
  23. begin
  24.   display := XOpenDisplay(nil);
  25.   if display = nil then Exit;
  26.  
  27.   keyCode := XKeysymToKeycode(display, keySym);
  28.  
  29.   event.display := display;
  30.   event.window := XDefaultRootWindow(display);
  31.   event.root := XDefaultRootWindow(display);
  32.   event.subwindow := None;
  33.   event.time := CurrentTime;
  34.   event.x := 1;
  35.   event.y := 1;
  36.   event.x_root := 1;
  37.   event.y_root := 1;
  38.   event.same_screen := 1;
  39.   event.keycode := keyCode;
  40.   event.state := 0;
  41.  
  42.   if shiftState then
  43.     event.state := event.state or ShiftMask;
  44.  
  45.   // Key press
  46.   event._type := KeyPress;
  47.   XSendEvent(display, XDefaultRootWindow(display), 1, KeyPressMask, @event);
  48.  
  49.   // Small delay (optional)
  50.   // Sleep(10);
  51.  
  52.   // Key release
  53.   event._type := KeyRelease;
  54.   XSendEvent(display, XDefaultRootWindow(display), 1, KeyReleaseMask, @event);
  55.  
  56.   XFlush(display);
  57.   XCloseDisplay(display);
  58. end;
  59.  
  60. procedure Simulate_Mouse_Click(x, y: integer; button: integer = 1);
  61. var
  62.   display: PDisplay;
  63.   event: TXButtonEvent;
  64. begin
  65.   display := XOpenDisplay(nil);
  66.   if display = nil then Exit;
  67.  
  68.   // Move mouse to position
  69.   XWarpPointer(display, None, XDefaultRootWindow(display), 0, 0, 0, 0, x, y);
  70.   XFlush(display);
  71.  
  72.   // Set up event
  73.   event.display := display;
  74.   event.window := XDefaultRootWindow(display);
  75.   event.root := XDefaultRootWindow(display);
  76.   event.subwindow := None;
  77.   event.time := CurrentTime;
  78.   event.x := x;
  79.   event.y := y;
  80.   event.x_root := x;
  81.   event.y_root := y;
  82.   event.same_screen := 1;
  83.   event.state := 0;
  84.   event.button := button;
  85.  
  86.   // Press
  87.   event._type := ButtonPress;
  88.   XSendEvent(display, XDefaultRootWindow(display), 1, ButtonPressMask, @event);
  89.   XFlush(display);
  90.  
  91.   // Release
  92.   event._type := ButtonRelease;
  93.   XSendEvent(display, XDefaultRootWindow(display), 1, ButtonReleaseMask, @event);
  94.   XFlush(display);
  95.  
  96.   XCloseDisplay(display);
  97. end;
  98.  
  99. procedure Simulate_Mouse_move(x, y: integer);
  100. var
  101.   display: PDisplay;
  102. begin
  103.   display := XOpenDisplay(nil);
  104.   if display = nil then Exit;
  105.  
  106.   XWarpPointer(display, None, XDefaultRootWindow(display), 0, 0, 0, 0, x, y);
  107.   XFlush(display);
  108.   XCloseDisplay(display);
  109. end;
  110.  
  111. end.
  112.  
Depends on X, not tested for Wayland, but XWayland works.

You can also use xdotool, which works like this:
Code: Pascal  [Select][+][-]
  1. procedure SimulateWithXdotool(command: string);
  2. begin
  3.   ExecuteProcess('/usr/bin/xdotool', command);
  4. end;
  5.  
  6. // Usage examples:
  7. // SimulateWithXdotool('key a');           // Press 'a'
  8. // SimulateWithXdotool('key Ctrl+c');      // Press Ctrl+C
  9. // SimulateWithXdotool('mousemove 100 100'); // Move mouse
  10. // SimulateWithXdotool('click 1');         // Left click
Needs xdotool installed: apt-get install xdotool

I have more examples, but these need root priviliges.
« Last Edit: October 29, 2025, 08:12:57 am by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: SendKeys Alernative for Linux
« Reply #3 on: October 29, 2025, 08:25:54 am »
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  [Select][+][-]
  1. procedure Simula]"]>BlockeduseClick(x, y: integer; button: integer = 1);
  2. 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)
« Last Edit: October 29, 2025, 08:37:06 am by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

MarkMLl

  • Hero Member
  • *****
  • Posts: 8533
Re: SendKeys Alernative for Linux
« Reply #4 on: October 29, 2025, 08:39:15 am »
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
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: SendKeys Alernative for Linux
« Reply #5 on: October 29, 2025, 08:43:08 am »
That needs root privileges, so I left that out. If you are interested I can post for that too..
Using /dev/uinput and fpioctrl. Not really recommended and I doubt if it is very useful to OP.
(Or anybody sane for that matter, usually discussions unfold that are not relevant to the question: a replacement for sendkeys)
« Last Edit: October 29, 2025, 09:00:13 am by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

MarkMLl

  • Hero Member
  • *****
  • Posts: 8533
Re: SendKeys Alernative for Linux
« Reply #6 on: October 29, 2025, 11:49:22 am »
That needs root privileges, so I left that out.

No, user needs to be a member of the input group, or the program he's running needs appropriate capabilities.

The sticking point is routing to a specific PID, window etc.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

pixelink

  • Hero Member
  • *****
  • Posts: 1269
Re: SendKeys Alernative for Linux
« Reply #7 on: October 29, 2025, 04:54:51 pm »
Thanks for the info!
Can't Type - Forgetful - Had Stroke = Forgive this old man!
LAZ 4.2.0 •  VSSTUDIO(.Net) 2022 • Win11 • 32G RAM • Nvida RTX 4070 Ti Super

LemonParty

  • Sr. Member
  • ****
  • Posts: 393
Re: SendKeys Alernative for Linux
« Reply #8 on: November 22, 2025, 01:40:50 pm »
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
I am intersting if someone successfully used this API.
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

MarkMLl

  • Hero Member
  • *****
  • Posts: 8533
Re: SendKeys Alernative for Linux
« Reply #9 on: November 22, 2025, 07:16:11 pm »
I am intersting if someone successfully used this API.

Not with my own code. I've got a slightly-modified version of mxk originally from http://welz.org.za/projects/mxk (not sure whether that site is still live **), but basically there should be plenty of examples around although they'll probably be written in C.

However as I've said: the problem is that it's global, and oblivious to what program's running etc. To decide whether that API is going to be any use at all for you I suggest playing with evtest, noting that you'll need to be a member of the input group.

MarkMLl

** https://web.archive.org/web/20150804022200/http://welz.org.za/projects/mxk
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

LemonParty

  • Sr. Member
  • ****
  • Posts: 393
Re: SendKeys Alernative for Linux
« Reply #10 on: November 23, 2025, 06:07:17 pm »
That is quite a lot of C code. But it well written C code. Will be challenging to extract what needed from this sources.
Thank you.
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

 

TinyPortal © 2005-2018