#!/usr/bin/env perl # /[un]load osd.pl # # Irssi script that displays chat lines one by one at the bottom of the desktop # # PURPOSE: # follow a (slow) chat while working with full screen real estate (no irssi window) # and without having to check irssi for new messages # # EXAMPLE OUTPUT: # joe_user (#example): # hi, guys. i'm testing my new irssi script # and it's pretty good # # REQUIRES: # - X::Osd (libxosd), try on root command line: cpan X::Osd # - access priviledges to X (if you run Irssi as another user) # # # TODO: # - "* nick does something" # - wait and do not skip old text if new text # - replace xosd lib with direct calls to osd_cat? concurrency problems? # - problems with special characters, e.g., > # - is_osd_sensible_now and multiple irssi instances? # - is_osd_sensible_now: WM_COMMAND *and* WM_NAME? use strict; use warnings; use X::Osd; use Irssi; our $VERSION = '2011-02-10'; our %IRSSI = ( authors => 'nachtrag.wordpress.com', contact => 'nachtrag.wordpress.com', url => 'http://nachtrag.wordpress.com/2011/02/06/on-screen-texteinblendungen-aus-dem-irc/', name => 'osd', description => 'Display chat lines one by one at the bottom of the desktop', created => '2011-02-05', changed => $VERSION, license => 'CC-BY-SA', ); # Initialize at load time our $osd = X::Osd::create(4); $osd->set_font("-*-helvetica-bold-r-normal-*-17-*-*-*-*-*-*-*"); $osd->set_timeout(5); $osd->set_pos(XOSD_bottom); $osd->set_align(XOSD_center); $osd->set_horizontal_offset(0); $osd->set_vertical_offset(10); $osd->set_colour("Green"); $osd->set_outline_colour("black"); $osd->set_outline_offset(2); $osd->set_shadow_offset(0); Irssi::signal_add_last( 'print text', 'text_printed' ); $osd->string( 0, 'OSD loaded' ); $osd->string( 1, 'Text appears unless you see Irssi' ); sub is_osd_sensible_now # returns bool { my ($irssi_win_id) = `xwininfo -root -tree | grep \"irssi\"` =~ / (0x[0-9a-f]*) /; my $is_irssi_visible = `xwininfo -id $irssi_win_id | grep IsViewable`; return not $is_irssi_visible; } sub text_printed { my $dest = shift; # Irssi::UI::TextDest my $text = shift; # ? my $stripped = shift; # string " bla" return if ( not $dest->{level} & MSGLEVEL_PUBLIC or not is_osd_sensible_now() ); # format OSD output: my ( $nick, $message ) = $stripped =~ /\<(.*)\>(.*)/; my @multiline_message = $message =~ /(.{1,60}\b)/gms; my $headline = $nick . ' (' . $dest->{target} . '):'; my @output = ( $headline, @multiline_message ); # display on screen: $osd->set_timeout( length $stripped < 50 ? 4 : 8 ); $#output = $osd->get_number_lines() - 1; # overwrite all lines my $line_index = 0; $osd->string( $line_index++, $_ ) foreach (@output); }