You are not logged in.
Hi,
I am using Urxvt and would like to change my cursor type if I enter keyboard select mode. For the keyboard select I am using following Perl script (https://github.com/muennich/urxvt-perls … ard-select).
I am able to change cursor type using zsh in a following way.
#!/bin/zsh
if [[ "$1" == "normal" ]]; then
print -n -- "\033[3 q"
elif [[ "$1" == "selection" ]]; then
print -n -- "\033[1 q"
fiI called this script urxvt-cursor.sh and I execute it in the following way:
./urxvt-cursor.sh normal./urxvt-cursor.sh selectionThis script works as expected, by running urxvt-cursor.sh selection my cursor turns into block, while urxvt-cursor.sh normal turns my cursor into underline.
I would like to execute this script at the moment when I enter selection mode with Perl script.
Here is what I've tried:
On line 447 (method activate within the Perl script ) I've added following piece of code:
system("zsh $HOME/script/urxvt-cursor.sh selection" )On line 496 (method deactivate within the Perl script) I've added following piece of code:
system("zsh $HOME/script/urxvt-cursor.sh normal")To ensure this code is executed, I've modified my code in a way:
#!/bin/zsh
if [[ "$1" == "normal" ]]; then
print -n -- "\033[3 q"
touch /tmp/a.txt
elif [[ "$1" == "selection" ]]; then
print -n -- "\033[1 q"
touch /tmp/b.txt
fiI can confirm files a.txt and b.txt do get created in my /tmp/ folder. The problem which likely occurs here is that system(...) call within Perl script is executed in subshell, therefore my cursor changes there.
Here is what is at my disposal:
Creating a zle functions in .zshrc:
urxvt_cursor_normal() {
print -n -- "\033[3 q"
}; zle -N urxvt_cursor_normal
urxvt_cursor_selection() {
print -n -- "\033[1 q"
}; zle -N urxvt_cursor_selectionAssigning those zle functions to keybinds do change my cursor as I am expecting them to do.
I can assign them to escape key ( ^[ ) - same key as my Perl script is assigned to, but urxvt keybinding has priority over zsh one.
URxvt.keysym.Escape: perl:keyboard-select:activateI would appreciate it if someone can help me in this task in order to change cursor type at the moment I enter selection mode within perl script.
Best,
jkovacevic
EDIT: Solution to my problem is following:
Adding at the start of sub activate:
$self->cmd_parse("\033[1 q");as well adding to start of sub deactivate:
$self->cmd_parse("\033[3 q");Last edited by jkovacevic (2019-06-12 08:00:39)
Offline
Whoa - cut out all those middle men. A perl script is perfectly capable of printing a character to the terminal on it's own. There's no need for a separate script in yet another shell called through subprocess (with or without any keybinding).
Instead of using the perl "system()" function, just use "print" and put the escape sequences right in the perl script to print to the terminal to change the cursor shape.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Whoa - cut out all those middle men. A perl script is perfectly capable of printing a character to the terminal on it's own. There's no need for a separate script in yet another shell called through subprocess (with or without any keybinding).
Instead of using the perl "system()" function, just use "print" and put the escape sequences right in the perl script to print to the terminal to change the cursor shape.
Here is what I've tried, but to no avail. Simply printing stuff using this Perl script does not reach console.
Line 447:
print "\033[1 q";print STDOUT "\033[1 q";Neither of those work. Is there a reason why Perl script cannot reach my standard output? Is it executed as "subprocess / in subshell"?
I would like note that adding this piece of code on Line 447 successfully creates a file with "Hello World" inside:
my $filename = '/tmp/perl-debug.log';
open($fh, '>>', $filename);
print $fh "Hello world", "\n";
close $fh;I can see the solution in either two scenarios:
a) print to standard output before Perl script "takes over" console.
This would mean I would need to somehow execute perl and zsh script within URxvt.keysym.Escape keybind; or the zsh keybind bindsym to Escape should be faster than URxvt one.
b) find a way to write to standard output within Perl script to console (preferred way)
But I cannot make progress in either of those ![]()
Last edited by jkovacevic (2019-06-07 07:14:39)
Offline
Ah, right, sorry. The perl script is run by urxvt, so the output goes to urxvt's stdout, not to the shell session within it. That being the case, there is no way a script called from within perl could print to the shell session.
The exception would be if you were able to find the relevant shell process in /proc and wrote to the relevant fd under it.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
I've made some progress, but still I am not there yet. If I write tty in one terminal I will get, for instance, dev/pts/0. If I open second terminal, and write:
print -n -- '\033[1 q' > /dev/pts/0I will change the cursor in the first terminal, therefore if I open only one terminal and write:
print -n -- '\033[1 q' > $(tty)The cursor is changed. Now lets, try in perl script (I hardcoded output of correct tty):
system("print -n -- '\033[1 q' > /dev/pts/0");but there is no effect. The script does not crash at least.
Ideas, am I outputting text to urxvt session again?
Last edited by jkovacevic (2019-06-08 10:16:59)
Offline
That is for the very same reason as the initial problem, if the perl script is running within any pty, it is within the pty that urxvt is running in not the pty created for the shell session started within urxvt.
To demonstrate this further, start urxvt from another terminal (or from another urxvt window). If urxvt creates any output or error messages, they will print to the first terminal window. Only output from the shell within the second urxvt window will show up in that shell. Further, I suspect that any output from the perl script will go to the first window that launched urxvt.
Note that `print ... > /dev/pts/0` is no different than just `print ...`; printing to the stdout is the default. The problem is that the perl script's stdout is not the shell's stdout.
EDIT: revision, /dev/pts/0 does indeed refer to a specific pts. But the problem is 0 may not be the right one. I was thinking of /proc/self which is different in each process.
In any case, while theoretically possible to search the process tree and potentially find the shell process to print to, I highly doubt that is a productive avenue to acheive your goal.
Last edited by Trilby (2019-06-08 11:46:03)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
In any case, while theoretically possible to search the process tree and potentially find the shell process to print to, I highly doubt that is a productive avenue to acheive your goal.
I have the same feeling, but I would at least try to achieve it.
My results are best viewed as video: https://streamable.com/opzts
Code I've used:
#!/bin/zsh
for pid in $(ps -ax | grep pts | grep zsh | cut -d ' ' -f 1); do print -n -- '\033[1 q' > /proc/$pid/fd/0; done;As you can see, problem is that Perl script takes over my terminal before cursor type can be changed. I've looked over the code and I cannot pinpoint the moment this is happening.
Is this battle futile?
Last edited by jkovacevic (2019-06-08 12:41:12)
Offline
I trap SIGUSR1 in my zshrc for a similar purpose (flip colors, daytime/redshift driven)
Offline
There is solution, but it is so ugly that I would rather drop it than use it.
zshrc
keyboard-select() {
print -n -- '\033[1 q';
xdotool key 76; # represents F10
}; zle -N keyboard-selectXdefaults
URxvt.keysym.F10: perl:keyboard-select:activatekeyboard-select Perl script in sub deactivate()
system("zsh $HOME/script/change-cursor-urxvt.sh");change-cursor-urxvt.sh
#!/bin/zsh
for pid in $(ps -ax | grep pts | grep zsh | awk '{ print $1 }'); do print -n -- '\033[3 q' > /proc/$pid/fd/0; done;If someone has any other idea, I would appreciate it.
Last edited by jkovacevic (2019-06-08 16:02:01)
Offline
That last script can certainly be drastically simplified:
for pid in $(ps -C zsh | awk '/pts/{ print $1; }'); do ...Last edited by Trilby (2019-06-08 18:17:35)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
I have contacted Marc Lehmann via email and here is his response:
It's not quite clear to me what the problem is, but if the goal is to send
a command sequence to urxvt from within a perl extebsion, it should be as
simple as this:$self->cmd_parse ("\033...");
cmd_parse is the function that parses command sequences such as the one
changing the cursor shape.
I can confirm, adding at the start of sub activate:
$self->cmd_parse("\033[1 q");as well adding to start of sub deactivate:
$self->cmd_parse("\033[3 q");fixes my problem completely and works as expected. Thank you all for help.
Offline
Please always remember to mark resolved threads by editing your initial posts subject - so others will know that there's no task left, but maybe a solution to find.
Thanks.
Offline