1use strict; # use warnings; 2 3# FIXME COULD SOMEONE PLEASE TELL ME HOW TO SHUT UP 4# 5# ... 6# Variable "*" will not stay shared at (eval *) line *. 7# Variable "*" will not stay shared at (eval *) line *. 8# ... 9# Can't locate package Irssi::Nick for @Irssi::Irc::Nick::ISA at (eval *) line *. 10# ... 11# 12# THANKS 13 14use Irssi (); # which is the minimum required version of Irssi ? 15use Irssi::TextUI; 16 17use vars qw($VERSION %IRSSI); 18 19$VERSION = '0.5'; 20%IRSSI = ( 21 authors => 'BC-bd, Veli, Timo \'cras\' Sirainen, Wouter Coekaerts, Nei', 22 contact => 'bd@bc-bd.org, veli@piipiip.net, tss@iki.fi, wouter@coekaerts.be, Nei@QuakeNet', 23 name => 'wlstat', 24 description => 'Adds a window list in the status area. Based on chanact.pl by above authors.', 25 license => 'GNU GPLv2 or later', 26); 27 28# adapted by Nei 29 30############### 31# original comment 32# ########### 33# # Adds new powerful and customizable [Act: ...] item (chanelnames,modes,alias). 34# # Lets you give alias characters to windows so that you can select those with 35# # meta-<char>. 36# # 37# # for irssi 0.8.2 by bd@bc-bd.org 38# # 39# # inspired by chanlist.pl by 'cumol@hammerhart.de' 40# # 41# ######### 42# # Contributors 43# ######### 44# # 45# # veli@piipiip.net /window_alias code 46# # qrczak@knm.org.pl chanact_abbreviate_names 47# # qerub@home.se Extra chanact_show_mode and chanact_chop_status 48# # 49# 50# FURTHER THANKS TO 51# ############ 52# # buu, fxn, Somni, Khisanth, integral, tybalt89 for much support in any aspect perl 53# # and the channel in general ( #perl @ freenode ) and especially the ir_* functions 54# # 55# # Valentin 'senneth' Batz ( vb@g-23.org ) for the pointer to grep.pl, continuous support 56# # and help in digging up ir_strip_codes 57# # 58# # OnetrixNET technology networks for the debian environment 59# # 60# # Monkey-Pirate.com / Spaceman Spiff for the webspace 61# # 62# 63 64###### 65# M A I N P R O B L E M 66##### 67# 68# It is impossible to place the wlstat on a statusbar together with other items, because I 69# do not know how to calculate the size that it is going to get granted, and therefore I 70# cannot do the linebreaks properly. 71# This is what is missing to make a nice script out of wlstat. 72# If you have any ideas, please contact me ASAP :). 73# 74###### 75 76###### 77# UTF-8 PROBLEM 78##### 79# 80# Please help me find a solution to this: 81# this be your statusbar, it is using up the maximum term size 82# [[1=1]#abc [2=2]#defghi] 83# 84# now consider this example: "ascii" characters are marked with ., utf-8 characters with * 85# [[1=1]#... [2=2]#...***] 86# 87# you should think that this is how it would be displayed? WRONG! 88# [[1=1]#... [2=2]#...*** ] 89# 90# this is what Irssi does.. I believe my length calculating code to be correct, however, I'd 91# love to be proven wrong (or receive any other fix, too, of course!) 92# 93###### 94 95######### 96# USAGE 97### 98# 99# copy the script to ~/.irssi/scripts/ 100# 101# In irssi: 102# 103# /script load wlstat 104# 105# 106# Hint: to get rid of the old [Act:] display 107# /statusbar window remove act 108# 109# to get it back: 110# /statusbar window add -after lag -priority 10 act 111# 112########## 113# OPTIONS 114######## 115# 116# /set wlstat_display_nokey <string> 117# /set wlstat_display_key <string> 118# * string : Format String for one window. The following $'s are expanded: 119# $C : Name 120# $N : Number of the Window 121# $Q : meta-Keymap 122# $H : Start highlighting 123# $S : Stop highlighting 124# IMPORTANT: don't forget to use $S if you used $H before! 125# 126# /set wlstat_separator <string> 127# * string : Charater to use between the channel entries 128# you'll need to escape " " space and "$" like this: 129# "/set wlstat_separator \ " 130# "/set wlstat_separator \$" 131# and {}% like this: 132# "/set wlstat_separator %{" 133# "/set wlstat_separator %}" 134# "/set wlstat_separator %%" 135# (reason being, that the separator is used inside a {format }) 136# 137# /set wlstat_hide_data <num> 138# * num : hide the window if its data_level is below num 139# set it to 0 to basically disable this feature, 140# 1 if you don't want windows without activity to be shown 141# 2 to show only those windows with channel text or hilight 142# 3 to show only windows with hilight 143# 144# /set wlstat_maxlines <num> 145# * num : number of lines to use for the window list (0 to disable) 146# 147# /set wlstat_sort <-data_level|-last_line|refnum> 148# * you can change the window sort order with this variable 149# -data_level : sort windows with hilight first 150# -last_line : sort windows in order of activity 151# refnum : sort windows by window number 152# 153# /set wlstat_placement <top|bottom> 154# /set wlstat_position <num> 155# * these settings correspond to /statusbar because wlstat will create 156# statusbars for you 157# (see /help statusbar to learn more) 158# 159# /set wlstat_all_disable <ON|OFF> 160# * if you set wlstat_all_disable to ON, wlstat will also remove the 161# last statusbar it created if it is empty. 162# As you might guess, this only makes sense with wlstat_hide_data > 0 ;) 163# 164### 165# WISHES 166#### 167# 168# if you fiddle with my mess, provide me with your fixes so I can benefit as well 169# 170# Nei =^.^= ( QuakeNet accountname: ailin ) 171# 172 173my $actString = []; # statusbar texts 174my $currentLines = 0; 175my $resetNeeded; # layout/screen has changed, redo everything 176my $needRemake; # "normal" changes 177#my $callcount = 0; 178my $globTime = undef; # timer to limit remake() calls 179 180my %statusbars; # currently active statusbars 181 182# maybe I should just tie the array ? 183sub add_statusbar { 184 for (@_) { 185 # add subs 186 for my $l ($_) { eval { 187 no strict 'refs'; # :P 188 *{"wlstat$l"} = sub { wlstat($l, @_) }; 189 }; } 190 Irssi::command("statusbar wl$_ reset"); 191 Irssi::command("statusbar wl$_ enable"); 192 if (lc Irssi::settings_get_str('wlstat_placement') eq 'top') { 193 Irssi::command("statusbar wl$_ placement top"); 194 } 195 if ((my $x = int Irssi::settings_get_int('wlstat_position')) != 0) { 196 Irssi::command("statusbar wl$_ position $x"); 197 } 198 Irssi::command("statusbar wl$_ add -priority 100 -alignment left barstar"); 199 Irssi::command("statusbar wl$_ add wlstat$_"); 200 Irssi::command("statusbar wl$_ add -priority 100 -alignment right barend"); 201 Irssi::command("statusbar wl$_ disable"); 202 Irssi::statusbar_item_register("wlstat$_", '$0', "wlstat$_"); 203 $statusbars{$_} = {}; 204 } 205} 206 207sub remove_statusbar { 208 for (@_) { 209 Irssi::command("statusbar wl$_ reset"); 210 Irssi::statusbar_item_unregister("wlstat$_"); # XXX does this actually work ? 211 # DO NOT REMOVE the sub before you have unregistered it :)) 212 for my $l ($_) { eval { 213 no strict 'refs'; 214 undef &{"wlstat$l"}; 215 }; } 216 delete $statusbars{$_}; 217 } 218} 219 220sub syncLines { 221 my $temp = $currentLines; 222 $currentLines = @$actString; 223 #Irssi::print("current lines: $temp new lines: $currentLines"); 224 my $currMaxLines = Irssi::settings_get_int('wlstat_maxlines'); 225 if ($currMaxLines > 0 and @$actString > $currMaxLines) { 226 $currentLines = $currMaxLines; 227 } 228 return if ($temp == $currentLines); 229 if ($currentLines > $temp) { 230 for ($temp .. ($currentLines - 1)) { 231 add_statusbar($_); 232 Irssi::command("statusbar wl$_ enable"); 233 } 234 } 235 else { 236 for ($_ = ($temp - 1); $_ >= $currentLines; $_--) { 237 Irssi::command("statusbar wl$_ disable"); 238 remove_statusbar($_); 239 } 240 } 241} 242 243my %keymap; 244 245sub get_keymap { 246 my ($textDest, undef, $cont_stripped) = @_; 247 if ($textDest->{'level'} == 524288 and $textDest->{'target'} eq '' and !defined($textDest->{'server'})) { 248 if ($cont_stripped =~ m/meta-(.)\s+change_window (\d+)/) { $keymap{$2} = "$1"; } 249 Irssi::signal_stop(); 250 } 251} 252 253sub update_keymap { 254 %keymap = (); 255 Irssi::signal_remove('command bind' => 'watch_keymap'); 256 Irssi::signal_add_first('print text' => 'get_keymap'); 257 Irssi::command('bind'); # stolen from grep 258 Irssi::signal_remove('print text' => 'get_keymap'); 259 Irssi::signal_add('command bind' => 'watch_keymap'); 260 Irssi::timeout_add_once(100, 'eventChanged', undef); 261} 262 263# watch keymap changes 264sub watch_keymap { 265 Irssi::timeout_add_once(1000, 'update_keymap', undef); 266} 267 268update_keymap(); 269 270sub expand { 271 my ($string, %format) = @_; 272 my ($exp, $repl); 273 $string =~ s/\$$exp/$repl/g while (($exp, $repl) = each(%format)); 274 return $string; 275} 276 277# FIXME implement $get_size_only check, and user $item->{min|max-size} ?? 278sub wlstat { 279 my ($line, $item, $get_size_only) = @_; 280 281 if ($needRemake) { 282 $needRemake = undef; 283 remake(); 284 } 285 286 my $text = $actString->[$line]; # DO NOT set the actual $actString->[$line] to '' here or 287 $text = '' unless defined $text; # you'll screw up the statusbar counter ($currentLines) 288 $item->default_handler($get_size_only, $text, '', 1); 289} 290 291my %strip_table = ( 292 # fe-common::core::formats.c:format_expand_styles 293 # delete format_backs format_fores bold_fores other stuff 294 (map { $_ => '' } (split //, '04261537' . 'kbgcrmyw' . 'KBGCRMYW' . 'U9_8:|FnN>#[')), 295 # escape 296 (map { $_ => $_ } (split //, '{}%')), 297); 298sub ir_strip_codes { # strip %codes 299 my $o = shift; 300 $o =~ s/(%(.))/exists $strip_table{$2} ? $strip_table{$2} : $1/gex; 301 $o 302} 303 304sub ir_parse_special { 305 my $o; my $i = shift; 306 my $win = Irssi::active_win(); 307 my $server = Irssi::active_server(); 308 if (ref $win and ref $win->{'active'}) { 309 $o = $win->{'active'}->parse_special($i); 310 } 311 elsif (ref $win and ref $win->{'active_server'}) { 312 $o = $win->{'active_server'}->parse_special($i); 313 } 314 elsif (ref $server) { 315 $o = $server->parse_special($i); 316 } 317 else { 318 $o = Irssi::parse_special($i); 319 } 320 $o 321} 322 323sub sb_expand { # expand {format }s (and apply parse_special for $vars) 324 ir_parse_special( 325 Irssi::current_theme->format_expand( 326 shift, 327 ( 328 Irssi::EXPAND_FLAG_IGNORE_REPLACES 329 | 330 Irssi::EXPAND_FLAG_IGNORE_EMPTY 331 ) 332 ) 333 ) 334} 335sub sb_strip { 336 ir_strip_codes( 337 sb_expand(shift) 338 ); # does this get us the actual length of that s*ty bar :P ? 339} 340sub sb_length { 341 # unicode cludge, d*mn broken Irssi 342 # screw it, this will fail from broken joining anyway (and cause warnings) 343 if (lc Irssi::settings_get_str('term_type') eq 'utf-8') { 344 my $temp = sb_strip(shift); 345 # try to switch on utf8 346 eval { 347 no warnings; 348 require Encode; 349 #$temp = Encode::decode_utf8($temp); # thanks for the hint, but I have my reasons for _utf8_on 350 Encode::_utf8_on($temp); 351 }; 352 length($temp) 353 } 354 else { 355 length(sb_strip(shift)) 356 } 357} 358 359# !!! G*DD*MN Irssi is adding an additional layer of backslashitis per { } layer 360# !!! AND I still don't know what I need to escape. 361# !!! and NOONE else seems to know or care either. 362# !!! f*ck open source. I mean it. 363# XXX any Irssi::print debug statement leads to SEGFAULT - why ? 364 365# major parts of the idea by buu (#perl @ freenode) 366# thanks to fxn and Somni for debugging 367# while ($_[0] =~ /(.)/g) { 368# my $c = $1; # XXX sooo... goto kills $1 369# if ($q eq '%') { goto ESC; } 370 371## <freenode:#perl:tybalt89> s/%(.)|(\{)|(\})|(\\|\$)/$1?$1:$2?($level++,$2):$3?($level>$min_level&&$level--,$3):'\\'x(2**$level-1).$4/ge; # untested... 372sub ir_escape { 373 my $min_level = $_[1] || 0; my $level = $min_level; 374 my $o = shift; 375 $o =~ s/ 376 ( %. ) | # $1 377 ( \{ ) | # $2 378 ( \} ) | # $3 379 ( \\ ) | # $4 380 ( \$(?=.) ) | # $5 381 ( \$ ) # $6 382 / 383 if ($1) { $1 } # %. escape 384 elsif ($2) { $level++; $2 } # { nesting start 385 elsif ($3) { if ($level > $min_level) { $level--; } $3 } # } nesting end 386 elsif ($4) { '\\'x(2**$level) } # \ needs \\escaping 387 elsif ($5) { '\\'x(2**$level-1) . '$' . '\\'x(2**$level-1) } # and $ needs even more because of "parse_special" 388 else { '\\'x(2**$level-1) . '$' } # $ needs \$ escaping 389 /gex; 390 $o 391} 392#sub ir_escape { 393# my $min_level = $_[1] || 0; my $level = $min_level; 394# my $o = shift; 395# $o =~ s/ 396# ( %. ) | # $1 397# ( \{ ) | # $2 398# ( \} ) | # $3 399# ( \\ | \$ ) # $4 400# / 401# if ($1) { $1 } # %. escape 402# elsif ($2) { $level++; $2 } # { nesting start 403# elsif ($3) { if ($level > $min_level) { $level--; } $3 } # } nesting end 404# else { '\\'x(2**($level-1)-1) . $4 } # \ or $ needs \\escaping 405# /gex; 406# $o 407#} 408 409sub ir_fe { # try to fix format stuff 410 my $x = shift; 411 # XXX why do I have to use two/four % here instead of one/two ?? answer: you screwed up in ir_escape 412 $x =~ s/([%{}])/%$1/g; 413 $x =~ s/(\\|\$)/\\$1/g; 414 #$x =~ s/(\$(?=.))|(\$)/$1?"\\\$\\":"\\\$"/ge; # I think this should be here (logic), but it doesn't work that way :P 415 #$x =~ s/\\/\\\\/g; # that's right, escape escapes 416 $x 417} 418 419sub remake () { 420 #$callcount++; 421 #my $xx = $callcount; Irssi::print("starting remake [ $xx ]"); 422 my ($hilight, $number, $display); 423 my $separator = '{sb_act_sep ' . Irssi::settings_get_str('wlstat_separator') . '}'; 424 my $custSort = Irssi::settings_get_str('wlstat_sort'); 425 my $custSortDir = 1; 426 if ($custSort =~ /^[-!](.*)/) { 427 $custSortDir = -1; 428 $custSort = $1; 429 } 430 431 $actString = []; 432 my ($line, $width) = (0, [Irssi::windows]->[0]{'width'} - sb_length('{sb x}')); 433 foreach my $win ( 434 sort { 435 ( 436 ( (int($a->{$custSort}) <=> int($b->{$custSort})) * $custSortDir ) 437 || 438 ($a->{'refnum'} <=> $b->{'refnum'}) 439 ) 440 } Irssi::windows 441 ) { 442 $actString->[$line] = '' unless defined $actString->[$line] or Irssi::settings_get_bool('wlstat_all_disable'); 443 444 # all stolen from chanact, what does this code do and why do we need it ? 445 !ref($win) && next; 446 447 my $name = $win->get_active_name; 448 my $active = $win->{'active'}; 449 my $colour = $win->{'hilight_color'}; 450 if (!defined $colour) { $colour = ''; } 451 452 if ($win->{'data_level'} < Irssi::settings_get_int('wlstat_hide_data')) { next; } # for Geert 453 if ($win->{'data_level'} == 0) { $hilight = '{sb_act_none '; } 454 elsif ($win->{'data_level'} == 1) { $hilight = '{sb_act_text '; } 455 elsif ($win->{'data_level'} == 2) { $hilight = '{sb_act_msg '; } 456 elsif ($colour ne '') { $hilight = "{sb_act_hilight_color $colour "; } 457 elsif ($win->{'data_level'} == 3) { $hilight = '{sb_act_hilight '; } 458 else { $hilight = '{sb_act_special '; } 459 460 $number = $win->{'refnum'}; 461 $display = (defined $keymap{$number} and $keymap{$number} ne '') 462 ? 463 ( 464 Irssi::settings_get_str('wlstat_display_key') 465 || 466 Irssi::settings_get_str('wlstat_display_nokey') 467 ) 468 : 469 Irssi::settings_get_str('wlstat_display_nokey') 470 ; 471 472 my $add = expand($display, 473 C => ir_fe($name), 474 N => $number, 475 Q => ir_fe($keymap{$number}), 476 H => $hilight, 477 S => '}{sb_background}' 478 ); 479 #$temp =~ s/\{\S+?(?:\s(.*?))?\}/$1/g; 480 #$temp =~ s/\\\\\\\\/\\/g; # XXX I'm actually guessing here, someone point me to docs please 481 $actString->[$line] = '' unless defined $actString->[$line]; 482 483 # XXX how can I check whether the content still fits in the bar? this would allow 484 # XXX wlstatus to reside on a statusbar together with other items... 485 if (sb_length(ir_escape($actString->[$line] . $add)) >= $width) { # XXX doesn't correctly handle utf-8 multibyte ... help !!? 486 $actString->[$line] .= ' ' x ($width - sb_length(ir_escape($actString->[$line]))); 487 $line++; 488 } 489 $actString->[$line] .= $add . $separator; 490 # XXX if I use these prints, output layout gets screwed up... why ? 491 #Irssi::print("line $line: ".$actString->[$line]); 492 #Irssi::print("temp $line: ".$temp); 493 } 494 495 # XXX the Irssi::print statements lead to the MOST WEIRD results 496 # e.g.: the loop gets executed TWICE for p > 0 ?!? 497 for (my $p = 0; $p < @$actString; $p++) { # wrap each line in {sb }, escape it properly, etc. 498 my $x = $actString->[$p]; 499 $x =~ s/\Q$separator\E([ ]*)$/$1/; 500 #Irssi::print("[$p]".'current:'.join'.',split//,sb_strip(ir_escape($x,0))); 501 #Irssi::print("assumed length before:".sb_length(ir_escape($x,0))); 502 $x = "{sb $x}"; 503 #Irssi::print("[$p]".'new:'.join'.',split//,sb_expand(ir_escape($x,0))); 504 #Irssi::print("[$p]".'new:'.join'.',split//,ir_escape($x,0)); 505 #Irssi::print("assumed length after:".sb_length(ir_escape($x,0))); 506 $x = ir_escape($x); 507 #Irssi::print("[$p]".'REALnew:'.join'.',split//,sb_strip($x)); 508 $actString->[$p] = $x; 509 # XXX any Irssi::print debug statement leads to SEGFAULT (sometimes) - why ? 510 } 511 #Irssi::print("remake [ $xx ] finished"); 512} 513 514sub wlstatHasChanged () { 515 $globTime = undef; 516 my $temp = Irssi::settings_get_str('wlstat_placement').Irssi::settings_get_int('wlstat_position'); 517 if ($temp ne $resetNeeded) { wlreset(); return; } 518 #Irssi::print("wlstat has changed, calls to remake so far: $callcount"); 519 $needRemake = 1; 520 521 #remake(); 522 if ( 523 ($needRemake and Irssi::settings_get_bool('wlstat_all_disable')) 524 or 525 (!Irssi::settings_get_bool('wlstat_all_disable') and $currentLines < 1) 526 ) { 527 $needRemake = undef; 528 remake(); 529 } 530 # XXX Irssi crashes if I try to do this without timer, why ? What's the minimum delay I need to use in the timer ? 531 Irssi::timeout_add_once(100, 'syncLines', undef); 532 533 for (keys %statusbars) { 534 Irssi::statusbar_items_redraw("wlstat$_"); 535 } 536} 537 538sub eventChanged () { # Implement a change queue/blocker -.-) 539 if (defined $globTime) { 540 Irssi::timeout_remove($globTime); 541 } # delay the update further 542 $globTime = Irssi::timeout_add_once(10, 'wlstatHasChanged', undef); 543} 544 545#$needRemake = 1; 546sub resizeTerm () { 547 Irssi::timeout_add_once(100, 'eventChanged', undef); 548} 549 550Irssi::settings_add_str('wlstat', 'wlstat_display_nokey', '[$N]$H$C$S'); 551Irssi::settings_add_str('wlstat', 'wlstat_display_key', '[$Q=$N]$H$C$S'); 552Irssi::settings_add_str('wlstat', 'wlstat_separator', "\\ "); 553Irssi::settings_add_int('wlstat', 'wlstat_hide_data', 0); 554Irssi::settings_add_int('wlstat', 'wlstat_maxlines', 9); 555Irssi::settings_add_str('wlstat', 'wlstat_sort', 'refnum'); 556Irssi::settings_add_str('wlstat', 'wlstat_placement', 'bottom'); 557Irssi::settings_add_int('wlstat', 'wlstat_position', 0); 558Irssi::settings_add_bool('wlstat', 'wlstat_all_disable', 0); 559 560# remove old statusbars 561my %killBar; 562sub get_old_status { 563 my ($textDest, $cont, $cont_stripped) = @_; 564 if ($textDest->{'level'} == 524288 and $textDest->{'target'} eq '' and !defined($textDest->{'server'})) { 565 if ($cont_stripped =~ m/^wl(\d+)\s/) { $killBar{$1} = {}; } 566 Irssi::signal_stop(); 567 } 568} 569sub killOldStatus { 570 %killBar = (); 571 Irssi::signal_add_first('print text' => 'get_old_status'); 572 Irssi::command('statusbar'); 573 Irssi::signal_remove('print text' => 'get_old_status'); 574 remove_statusbar(keys %killBar); 575} 576#killOldStatus(); 577 578sub wlreset { 579 $actString = []; 580 $currentLines = 0; # 1; # mhmmmm .. we actually enable one line down there so let's try this. 581 $resetNeeded = Irssi::settings_get_str('wlstat_placement').Irssi::settings_get_int('wlstat_position'); 582 #update_keymap(); 583 killOldStatus(); 584 # Register statusbar 585 #add_statusbar(0); 586 #Irssi::command('statusbar wl0 enable'); 587 resizeTerm(); 588} 589 590wlreset(); 591 592my $Unload; 593sub unload ($$$) { 594 $Unload = 1; 595 Irssi::timeout_add_once(10, sub { $Unload = undef; }, undef); # pretend we didn't do anything ASAP 596} 597Irssi::signal_add_first('gui exit' => sub { $Unload = undef; }); # last try to catch a sigsegv 598sub UNLOAD { 599 if ($Unload) { # this might well crash Irssi... try /eval /script unload someotherscript ; /quit (= SEGFAULT !) 600 $actString = ['']; # syncLines(); # XXX Irssi crashes when trying to disable all statusbars ? 601 killOldStatus(); 602 } 603} 604 605sub addPrintTextHook { # update on print text 606 return if $_[0]->{'level'} == 262144 and $_[0]->{'target'} eq '' and !defined($_[0]->{'server'}); 607 if (Irssi::settings_get_str('wlstat_sort') =~ /^[-!]?last_line$/) { 608 Irssi::timeout_add_once(100, 'eventChanged', undef); 609 } 610} 611 612#sub _x { my ($x, $y) = @_; ($x, sub { Irssi::print('-->signal '.$x); eval "$y();"; }) } 613#sub _x { @_ } 614Irssi::signal_add_first( 615 'command script unload' => 'unload' 616); 617Irssi::signal_add_last({ 618 'setup changed' => 'eventChanged', 619 'print text' => 'addPrintTextHook', 620 'terminal resized' => 'resizeTerm', 621 'setup reread' => 'wlreset', 622 'window hilight' => 'eventChanged', 623}); 624Irssi::signal_add({ 625 'window created' => 'eventChanged', 626 'window destroyed' => 'eventChanged', 627 'window name changed' => 'eventChanged', 628 'window refnum changed' => 'eventChanged', 629 'window changed' => 'eventChanged', 630 'window changed automatic' => 'eventChanged', 631}); 632 633#Irssi::signal_add('nick mode changed', 'chanactHasChanged'); # relicts 634 635############### 636### 637# 638# Changelog 639# 640# 0.5a 641# - add setting to also hide the last statusbar if empty (wlstat_all_disable) 642# - reverted to old utf8 code to also calculate broken utf8 length correctly 643# - simplified dealing with statusbars in wlreset 644# 645# 0.4d 646# - fixed order of disabling statusbars 647# - several attempts at special chars, without any real success 648# and much more weird new bugs caused by this 649# - setting to specify sort order 650# - reduced timeout values 651# - added wlstat_hide_data for Geert Hauwaerts ( geert@irssi.org ) :) 652# - make it so the dynamic sub is actually deleted 653# - fix a bug with removing of the last separator 654# - take into consideration parse_special 655# 656# 0.3b 657# - automatically kill old statusbars 658# - reset on /reload 659# - position/placement settings 660# 661# 0.2 662# - automated retrieval of key bindings (thanks grep.pl authors) 663# - improved removing of statusbars 664# - got rid of status chop 665# 666# 0.1 667# - rewritten to suit my needs 668# - based on chanact 0.5.5 669 670