new font-switcher Perl extension

Adam Spiers rxvt-unicode at adamspiers.org
Wed Jan 21 14:42:54 CET 2009


Hi all,

Just (re)discovered rxvt-unicode this weekend - hadn't realised how
much it had come on, with really great stuff like RGBA support and the
Perl extensions system.

I knocked up a quick font-switching extension to allow switching of
fonts on the fly via keyboard shortcuts - see attached.  Needless to
say it would be cool to extend this to incorporate a popup-menu
showing the same list!  If you like it feel free to include it in the
distribution.

Regards,
Adam
-------------- next part --------------
#!/usr/bin/perl
#
# font-switcher plugin for rxvt-unicode
# Copyright (C) 2009 Adam Spiers <urxvt-font-switcher at adamspiers.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


# This rxvt-unicode extension allows on-the-fly changing of fonts by
# moving left/right through a chosen list of fonts.  The list is
# delimited by '|' and configurable via X resources, e.g.
#
#   URxvt.font-switcher-list:  Micro|nexus|9x15|10x20
#
# Next/previous keys should also be bound for moving through the list,
# e.g.
#
#   URxvt.keysym.M-C-comma:  perl:font-switcher:previous
#   URxvt.keysym.M-C-period: perl:font-switcher:next

use strict;
use warnings;

my @font_list;

sub timed_popup {
  my ($term, $text, $timeout) = @_;
  $term->{'font-switcher'}{'overlay'} = {
    ov => $term->overlay_simple (0, -1, $text),
    to => urxvt::timer
      ->new
      ->start (urxvt::NOW + $timeout)
      ->cb(sub {
             delete $term->{'font-switcher'}{'overlay'};
           }),
  };
}

sub on_init {
  my ($term) = @_;
  my $font_list = $term->x_resource('font-switcher-list');
  if ($font_list) {
    @font_list = split /\|\s*/, $font_list;
  }
}


sub on_user_command {
  my ($term, $string) = @_;
  unless (@font_list) {
    timed_popup($term, "font-switcher-list resource was empty", 2);
    return;
  }

  my $current_font = $term->resource('font');
  my $current_index;
  for my $i (0 .. $#font_list) {
    if ($current_font eq $font_list[$i]) {
      $current_index = $i;
      last;
    }
  }

  unless ($string =~ /^font-switcher:(previous|next)$/i) {
    timed_popup($term, "keysym command should be 'font-switcher:previous' or 'font-switcher:next'", 2);
    return;
  }
  my $command = $1;
  my $direction = $command eq 'next' ? 1 : -1;

# This way wraps round
#   my $new_index = defined $current_index ?
#     ($current_index + $direction) % @font_list : 0;

  # This way has a hard stop at the start or end of the list.
  my $new_index = defined $current_index ?
    ($current_index + $direction) : 0;
  $new_index = 0 if $new_index < 0;
  $new_index = $#font_list if $new_index > $#font_list;

  my $new_font = $font_list[$new_index];
  timed_popup($term, "$new_index $new_font", 0.5);

  # This has no effect by itself, but is used for the next time we
  # lookup.  Also seems the Right Thing To Do.
  $term->resource('font', $new_font);

  # There's no API for changing font yet...
  # http://thread.gmane.org/gmane.comp.terminal-emulators.rxvt-unicode.general/255
  # $term->set_fonts($new_font);

  # so we do it via an escape sequence:
  $term->cmd_parse(sprintf "\33]50;%s\007", $new_font);

  $term->want_refresh; # seems to help
}


More information about the rxvt-unicode mailing list