Created
July 9, 2019 01:26
-
-
Save nobrowser/cbe0b6b23ef1d5dd791554f03e9831f3 to your computer and use it in GitHub Desktop.
Choose a window ID under bspwm via dmenu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/sh localperl | |
# This is actually -*-Perl-*- code | |
use strict; | |
use warnings; | |
use FileHandle; | |
use IPC::Open2; | |
use Getopt::Long; | |
use Text::Shorten qw(shorten_scalar); | |
use X11::Xlib; | |
use X11::Xlib::Display; | |
$main::display = X11::Xlib::Display->new; | |
$main::atomname = X11::Xlib::XInternAtom($main::display, 'WM_NAME', 0); | |
$main::atomstring = X11::Xlib::XInternAtom($main::display, 'STRING', 0); | |
$main::root = $main::display->RootWindow; | |
my ($xroot, $xparent) = (undef, undef); | |
@main::xkids = undef; | |
($xroot, $xparent, @main::xkids) = X11::Xlib::XQueryTree($main::display, $main::root); | |
sub get_window_name { | |
our ($display, $atomname, $atomstring, @xkids); | |
my $xid = $_[0]; | |
return undef unless grep { $_ == $xid } @xkids; | |
my @atoms = X11::Xlib::XListProperties($display, $xid); | |
return undef unless grep { $_ == $atomname } @atoms; | |
my ($xtype, $xformat, $xitems, $xafter, $xdata) = (undef, undef, undef, undef, undef); | |
my $retval = X11::Xlib::XGetWindowProperty($display, $xid, $atomname, 0, 32, 0, $atomstring, | |
$xtype, $xformat, $xitems, $xafter, $xdata); | |
return undef if !defined $retval || $retval || !$xdata; | |
return $xdata; | |
} | |
sub safe_pipe { | |
my @argv = @_; | |
open(my $fh, "-|") || exec @argv; | |
my @lines; | |
while (<$fh>) { | |
push @lines, $_; | |
} | |
close $fh; | |
return @lines; | |
} | |
my @win_ids = safe_pipe('bspc', 'query', '-N'); | |
my $brief; | |
GetOptions("brief" => \$brief); | |
my %ids_by_names; | |
GET_NAMES: | |
foreach my $windowid (@win_ids) { | |
chomp $windowid; | |
next GET_NAMES unless $windowid =~ m(^0x[0-9a-f]+$)i; | |
my $nameline = get_window_name(hex($windowid)); | |
next GET_NAMES unless $nameline; | |
next GET_NAMES unless $nameline =~ m(^\s*(\S(.*\S)?)\s*$) ; | |
$nameline = $1; | |
if ($brief) { | |
$nameline =~ s(^[^[:alpha:]]*)(); next GET_NAMES unless $nameline; | |
$nameline = shorten_scalar($nameline, 16); | |
} | |
$ids_by_names{$nameline} = $windowid; | |
} | |
exit(1) unless %ids_by_names; | |
my $pid = open2(*Reader, *Writer, "dmenu -i"); | |
while (my ($k, $v) = each %ids_by_names) { | |
printf Writer ("%s\n", $k); | |
} | |
close Writer; | |
my $selected_name = <Reader>; | |
waitpid($pid, 0); | |
exit(1) unless $selected_name; | |
chomp $selected_name; | |
print STDOUT $ids_by_names{$selected_name}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment