On Fri, 30 Nov 2007 13:45:50 -0600 Ted Zlatanov <[EMAIL PROTECTED]> wrote: 

TZ> On Fri, 30 Nov 2007 14:16:21 +0900 sqweek <[EMAIL PROTECTED]> wrote: 
s> On Nov 28, 2007 11:48 PM, Ted Zlatanov <[EMAIL PROTECTED]> wrote:
>>> I'd like to associate a corner/side of the screen with an action,
>>> similar to what the Gnome app Brightside or the Mac OS X corners do.  It
>>> needs to have a configurable delay and size of the active zone.  For
>>> example, moving the mouse to the top right could start xlock.
>>> Brightside doesn't work outside of Gnome, so it's not an option.
>>> 
>>> I don't know if this belongs in wmii or in an external utility, but
>>> haven't found anything that does it.  I think it's very useful.

s> wmii doesn't have any facilities to assist, so you'll have to use
s> some external app (which probably just creates an InputOnly window on
s> the edge of the screen).  -sqweek

TZ> It's basically xeyes with extra logic for resting the pointer in a
TZ> corner.  I wish I knew X programming enough to do this myself.  Maybe as
TZ> a side project I'll get to it.

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 spot 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

#!/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{1..4};
  return;
 }

 $state->{$spot}++;

 if ($spot != $state->{last})
 {
  delete @state{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};
}

Reply via email to