running shell commands when the mouse hits a corner

Ted Zlatanov <tzz-mIZUurteI1BWk0Htik3J/[email protected]>
Newsgroups gmane.comp.window-managers.ion.general
Organization Теодор Златанов @ Cienfuegos
Message-ID <[email protected]>
(I also posted this to the wmii mailing list, but thought Ion users
might like it too)

I found the xmousepos utility (part of the xautomation package).  I
wrote a simple Perl script, using xmousepos, which is run like this:

poscycle.pl -2 'xlock -mode matrix' 
(run that command when corner 2, top right, is hit)

poscycle.pl understands the xmousepos 'X Y ...' format, so any
application that prints the mouse cursor position as a single line of
output would work.  poscycle.pl has a -idle option for how long to wait,
and -size for how big the "hit" spot should be.  It cycles every second
so I doubt it's a big CPU hog.

Also, the X and Y dimensions are set to 1920x1200 in the script, but can
be overridden with -x and -y respectively.  I don't know how to grab
those automatically.

I hope it's useful to someone.

Ted
poscycle.pl (text/x-perl, 2.1 KB)
#!/usr/bin/perl

use warnings;
use strict;
use Data::Dumper;
use Getopt::Long;

use constant XMOUSEPOS => 'xmousepos';

my %options =
 (
  x => 1920,
  y => 1200,
  1 => '',				# TL
  2 => '',				# TR
  3 => '',				# BR
  4 => '',				# BL
  idle => 3,
  size => 15,
 );

GetOptions (
	    \%options,
	    "x=i",
	    "y=i",
	    "1|tl=s",
	    "2|tr=s",
	    "3|br=s",
	    "4|bl=s",
	    "i|idle=i",
	    "s|size=i",
	    "h|help",
	   );

if (exists $options{help})
{
 print <<EOHIPPUS;
$0

Options (defaults shown):
  X and Y dimensions of the monitor:
  --x $options{x}
  --y $options{y}

  Idle time before triggering a command (in seconds):
  --idle $options{idle} (or -i)

  Spot size in pixels:
  --size $options{size}

  Commands to run (numbered from top left, empty by default):
  --1 COMMAND # also --tl
  --2 COMMAND # also --tr
  --3 COMMAND # also --br
  --4 COMMAND # also --bl

EOHIPPUS
 exit;
}

my %state = (last => -1);

while (1)
{
 open X, XMOUSEPOS() . '|';
 $_ = <X>;
 my ($x, $y) = m/(\d+)\s+(\d+)/;
 close X;
# printf "coords %d %d\n", $x, $y;
 my $command = choose_command(\%state, \%options, $x, $y);
 sleep 1;
}

sub get_spot
{
  my $options = shift @_;
  my $x       = shift @_;
  my $y       = shift @_;

  return 1 if $x < $options->{size}                 && $y < $options->{size};
  return 2 if $x > $options->{x}-2-$options->{size} && $y < $options->{size};
  return 3 if $x > $options->{x}-2-$options->{size} && $y > $options->{y}-2-$options->{size};
  return 4 if $x < $options->{size}                 && $y > $options->{y}-2-$options->{size};

  return undef;
}

sub choose_command
{
 my $state   = shift @_;
 my $options = shift @_;
 my $x       = shift @_;
 my $y       = shift @_;

 my $spot = get_spot($options, $x, $y);

 unless (defined $spot)
 {
  delete $state->{$_} foreach 1..4;
  return;
 }

 $state->{$spot}++;

 if ($spot != $state->{last})
 {
  delete $state->{$_} foreach (grep { $_ ne $spot } keys %$state);
  $state->{last} = $spot;
 }

# print Dumper $state;

 return if $state->{$spot} != $options->{idle};
 
 return unless $options->{$spot};
 print "Triggered command $options->{$spot}\n";
 system $options->{$spot};
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.