Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- # Written by Mason Loring Bliss.
- # This program is explicitly in the public domain.
- use strict;
- use warnings;
- my $wmctrl = '/usr/bin/wmctrl';
- my $xprop = '/usr/bin/xprop';
- my $aw;
- my $ad;
- my @potentials;
- my %overlaps;
- my %w;
- my $command = shift || 'nothing';
- if ($command ne "left" && $command ne "right"
- && $command ne "up" && $command ne "down") {
- print "Sorry, need one of 'left', 'right', 'up', or 'down'.\n";
- exit 1;
- }
- if (! -f $xprop) {
- print "Sorry, we need $xprop to continue.\n";
- exit 1;
- }
- if (! -f $wmctrl) {
- print "Sorry, we need $wmctrl to continue.\n";
- exit 1;
- }
- # Find active window.
- open my $query, "$xprop -root|";
- while (<$query>) {
- last if /_NET_ACTIVE_WINDOW/;
- }
- (undef, undef, undef, undef, $aw) = split;
- close $query;
- $aw = sprintf("0x%08x", hex($aw));
- # Gather list of desktops, and note active desktop.
- open $query, "$wmctrl -d|";
- while (<$query>) {
- my ($dnum, $starred, undef) = split;
- if ($starred eq '*') {
- $ad = $dnum;
- last;
- }
- }
- close $query;
- # Gather list of windows on the active desktop, and their geometry.
- open $query, "$wmctrl -l -G|";
- while (<$query>) {
- my ($win, $desktop, $x, $y, $w, $h, undef) = split;
- next if $desktop ne $ad;
- # XXX possibly consider excluding gnome-panel
- $w{$win}{x} = $x;
- $w{$win}{y} = $y;
- $w{$win}{w} = $w;
- $w{$win}{h} = $h;
- }
- close $query;
- # Identify windows to consider.
- if ($command eq 'left') {
- @potentials = grep {$w{$_}{x} < $w{$aw}{x}} keys %w;
- } elsif ($command eq 'right') {
- @potentials =
- grep {$w{$_}{x} + $w{$_}{w} > $w{$aw}{x} + $w{$aw}{w}} keys %w;
- } elsif ($command eq 'up') {
- @potentials = grep {$w{$_}{y} < $w{$aw}{y}} keys %w;
- } else { # $command eq 'down'
- @potentials =
- grep {$w{$_}{y} + $w{$_}{h} > $w{$aw}{y} + $w{$aw}{h}} keys %w;
- }
- for (@potentials) {
- # Find x overlap.
- if ($w{$_}{x} < $w{$aw}{x}
- && $w{$_}{x} + $w{$_}{w} > $w{$aw}{x} + $w{$aw}{w}) {
- $overlaps{$_}{x} = $w{$aw}{w};
- } elsif ($w{$_}{x} > $w{$aw}{x}
- && $w{$_}{x} + $w{$_}{w} < $w{$aw}{x} + $w{$aw}{w}) {
- $overlaps{$_}{x} = $w{$aw}{w};
- } elsif ($w{$_}{x} < $w{$aw}{x}) {
- $overlaps{$_}{x} = $w{$_}{x} + $w{$_}{w} - $w{$aw}{x};
- } else {
- $overlaps{$_}{x} = $w{$aw}{x} + $w{$aw}{w} - $w{$_}{x};
- }
- # Find y overlap.
- if ($w{$_}{y} < $w{$aw}{y}
- && $w{$_}{y} + $w{$_}{h} > $w{$aw}{y} + $w{$aw}{h}) {
- $overlaps{$_}{y} = $w{$aw}{h};
- } elsif ($w{$_}{y} > $w{$aw}{y}
- && $w{$_}{y} + $w{$_}{h} < $w{$aw}{y} + $w{$aw}{h}) {
- $overlaps{$_}{y} = $w{$aw}{h};
- } elsif ($w{$_}{y} < $w{$aw}{y}) {
- $overlaps{$_}{y} = $w{$_}{y} + $w{$_}{h} - $w{$aw}{y};
- } else {
- $overlaps{$_}{y} = $w{$aw}{y} + $w{$aw}{h} - $w{$_}{y};
- }
- if ($command eq 'left' || $command eq 'right') {
- $overlaps{$_}{value} = $overlaps{$_}{y} * 1.5 + $overlaps{$_}{x};
- } else {
- $overlaps{$_}{value} = $overlaps{$_}{y} + $overlaps{$_}{x} * 1.5;
- }
- }
- # If there are no potentials, don't move. Otherwise, find the largest value.
- if (@potentials) {
- my $winner;
- my $high_water_mark;
- for (@potentials) {
- $winner //= $_;
- $high_water_mark //= $overlaps{$_}{value};
- if ($overlaps{$_}{value} > $high_water_mark) {
- $winner = $_;
- $high_water_mark = $overlaps{$_}{value};
- }
- }
- system("$wmctrl -i -a $winner");
- }
Add Comment
Please, Sign In to add comment