Get focused window title(name) using X11::Protocol

Use GetInputFocus() to get current focused window and use GetProperty() to get name of window.

use X11::Protocol;
my $x11 = X11::Protocol->new;
my ($focuswin) = $x11->GetInputFocus;
my ($title) = $x11->GetProperty(
    $focuswin, $x11->atom('WM_NAME'), $x11->atom('STRING'), 0, ~0, 0
);
print $title, "\n"; #=> Focused window title

Actually this doesn't work fine. There is a case which return value of GetInputFocus() is a nested window and the fact window that holds window title and you are looking for is the ancestor of it.

So the correct impl to get currently focused top-level window is like following:

use X11::Protocol;
my $x11 = X11::Protocol->new;
my ($focuswin) = $x11->GetInputFocus;
while (1) {
    my ($wmstate) = $x11->GetProperty(
        $focuswin, $x11->atom('WM_NAME'), 'AnyPropertyType', 0, ~0, 0
    );
    last if $wmstate; # Window has WM_STATE which means this is top-level window
    my (undef, $parent) = $x11->QueryTree($focuswin); # Lookup for parent window
    $focuswin = $parent;
}
my ($title) = $x11->GetProperty(
    $focuswin, $x11->atom('WM_NAME'), $x11->atom('STRING'), 0, ~0, 0
);
print $title, "\n"; #=> Focused window title

Furthermore we should prefer _NET_WM_NAME property instead of WM_NAME property to support window title in UTF-8 encoded but should still look for WM_NAME for fallback. So the final code is like following:

use X11::Protocol;
my $x11 = X11::Protocol->new;
my ($focuswin) = $x11->GetInputFocus;
while (1) {
    my ($wmstate) = $x11->GetProperty(
        $focuswin, $x11->atom('WM_NAME'), 'AnyPropertyType', 0, ~0, 0
    );
    last if $wmstate; # Window has WM_STATE which means this is top-level window
    my (undef, $parent) = $x11->QueryTree($focuswin); # Lookup for parent window
    $focuswin = $parent;
}
my ($title) = $x11->GetProperty(
    $focuswin, $x11->atom('_NET_WM_NAME'), $x11->atom('UTF8_STRING'), 0, ~0, 0
);
unless ($title) {
    # Fallback to WM_NAME
    ($title) = $x11->GetProperty(
        $focuswin, $x11->atom('WM_NAME'), $x11->atom('STRING'), 0, ~0, 0
    );
}
print $title, "\n"; #=> Focused window title

ref: https://github.com/jordansissel/xdotool/blob/master/xdo.c#L1220