アクティブなウインドウを四隅に移動させる
いろいろと作業をしていると別のウインドウを見つつしたいから, ちょっと
隅まで移動させたいということがあります. マウスで移動させてもいいのですが,
キーボード操作で移動できた方がいいかな, ということで書いてみました.
利用したコマンド
- wmctrl
- xprop
- xwininfo
- zenity
これらのコマンドです. zenityはエラー表示だけです.
xprop, xwininfoは X Window System使ってればたぶん入っているもの
だと思うので, wmctrlをインストールすれば使えると思います.
コード
シェルスクリプトで書くような内容だと思うのですが, シェルスクリプトは
超絶に苦手なので Perlで書きました.
追記 2011-09-14 コード修正
#!/home/syohei/perl5/perlbrew/perls/perl-5.14.1/bin/perl use strict; use warnings; use File::Which qw/which/; use utf8; use Encode qw(encode_utf8); local $SIG{__DIE__} = sub { exec qw/zenity --error --text/, encode_utf8(shift); }; check_environment(); my $direction = shift or die "Usage: $0 [top|right|bottom|left]"; my ($desktop_width, $desktop_height); my $id = get_display_info(); my $window_info = get_window_info($id); move_window($window_info); sub get_display_info { my @cmd = qw/xprop -root/; open my $fh, '-|', @cmd or die "Can't exec '@cmd'"; my $window_id; my ($is_set_window_size, $does_get_id) = (0, 0); while ( my $line = <$fh> ) { chomp $line; if ($line =~ m{^_NET_DESKTOP_GEOMETRY [^=]+ = \s+ (\d+), \s+ (\d+)}x) { ($desktop_width, $desktop_height) = ($1, $2); $is_set_window_size = 1; } if ($line =~ m{^_NET_ACTIVE_WINDOW}) { if ($line =~ m{window \s+ id \s+ \# \s+ ( [^\s,]+ )}x) { $window_id = $1; $does_get_id = 1; } } last if $is_set_window_size && $does_get_id; } close $fh; unless ($is_set_window_size && $does_get_id) { die "Can't get window info"; } return $window_id; } sub move_window { my $window_info = shift; my $panel_height = 0; if ($ENV{DESKTOP_SESSION} ne 'gnome') { $panel_height = get_panel_height(); } my @cmd = ('wmctrl', '-i', '-r', $window_info->{id}, '-e'); my $move_parameter; if ($direction eq 'top') { my $y_pos = $panel_height; $move_parameter = "0,-1,$panel_height,-1,-1"; } elsif ($direction eq 'right') { my $x_pos = $desktop_width - $window_info->{width}; $move_parameter = "0,$x_pos,-1,-1,-1"; } elsif ($direction eq 'bottom') { my $y_pos = $desktop_height - $window_info->{height} - $panel_height; $move_parameter = "0,-1,$y_pos,-1,-1"; } elsif ($direction eq 'left') { $move_parameter = '0,0,-1,-1,-1'; } else { die "Unknown direction '$direction'"; } push @cmd, $move_parameter; system(@cmd) == 0 or die "Can't exec '@cmd'"; } sub get_panel_height { my @cmd = qw/wmctrl -l -G/; open my $fh, "-|", @cmd or die "Can't exec '@cmd'"; my $panel_height = 0; while ( my $line = <$fh> ) { chomp $line; if ( $line =~ m{xfce4-panel} ) { my ($id, $workspace, $x_pos, $y_pos, $width, $height, @rest) = split /\s+/, $line; $panel_height = $height; last; } } close $fh; return $panel_height; } sub get_window_info { my $id = shift; my @cmd = (qw/xwininfo -id/, $id); open my $fh, '-|', @cmd or die "Can't exec '@cmd'"; my $window_info = { id => $id }; while ( my $line = <$fh> ) { chomp $line; if ($line =~ m{Width:\s+(\d+)}) { $window_info->{width} = $1; } elsif ($line =~ m{Height:\s+(\d+)}) { $window_info->{height} = $1; } } close $fh; return $window_info; } sub check_environment { for my $cmd (qw/wmctrl xprop xwininfo zenity/) { die "Please install '$cmd'" unless defined which($cmd); } }
GNOMEの場合, パネルを考慮して動いてしまうのですが, xfce4の場合
パネルにめり込んでしまう場合があったので, それを考慮しています.
私がインストール後にいろいろいじったせいかもしれないですのです,
環境に合わせてその辺は修正すればよいかと思います.
このスクリプトに実行権限を与えて, /usr/local/binや $HOME/binに置きます.
使用する Perlが /usr/binや /usr/local/binでない場合(perlbrewを使用)は
shebangはフルパスで指定してください. キーボードショートカットに割り当てる
とき, どこかでパスを明示的に指定してやれば問題ないと思いますが, .bashrc
や .zshrc等で設定することが多いと思うので, フルパスが無難です.
利用方法
% window_move.pl [top|right|bottom|left]
端末エミュレータで入力してしまうとその端末エミュレータのみと
なってしまうので, ウインドウマネージャのショートカットキーに
割り当てます.
xfce4であれば
「設定マネージャ」=>「キーボード」=>「アプリケーションショートカット」
から設定できます.
私は以下のように設定しました.
これで Superキー + 上下左右でウインドウが隅から隅へと動きます.
まとめ
コマンドでウインドウを移動させる方法を示しました.
タイル型ウインドウマネージャを使えばデフォルトでこんな
機能が備わっていると思うんだけど, 慣れ親しんだものから
変えるっていうのはなかなかできないので, 今の環境で
なんとかできないかと検討し, コードを書きました.