You are not logged in.
When I run "urxvt -pe tabbed", the bottom line of the terminal stays blank. Can anyone confirm this bug?
Anyways, if someone cares, I modified the perl source to add a few features:
- Remove the ugly "NEW" button, replace it with text (people know the shift-down shortcut anyways...)
- Better default colors (subject to taste...)
- Tabs only show when there is more than one terminal
- Fixed the unused bottom line bug
Also, to set the colors of the tabs in Xdefault, you need to use the "URxvt.tabbed" prefix with this exact case, otherwise it gets ignored (I don't know how to make it case insensitive in a clean way).
Use with "urxvt --perl-lib /path/to/script -pe script-name" (or install in the right place and set Xdefault accordingly)
#! perl
sub refresh {
my ($self) = @_;
#if(scalar(@{$self->{tabs}}) == 1) {
# return $self->want_refresh;
#}
my $ncol = $self->ncol;
my $text = " " x $ncol;
my $rend = [($self->{rs_tabbar}) x $ncol];
my @ofs;
#substr $text, 0, 7, "[NEW] |";
substr $text, 0, 6, "urxvt|";
#@$rend[0 .. 5] = ($self->{rs_tab}) x 6;
#push @ofs, [0, 6, sub { $_[0]->new_tab }];
#my $ofs = 7;
my $ofs = 6;
my $idx = 0;
for my $tab (@{ $self->{tabs} }) {
$idx++;
my $act = $tab->{activity} && $tab != $self->{cur}
? "*" : " ";
my $txt = "$act$idx$act";
my $len = length $txt;
substr $text, $ofs, $len + 1, "$txt|";
@$rend[$ofs .. $ofs + $len - 1] = ($self->{rs_tab}) x $len
if $tab == $self->{cur};
push @ofs, [ $ofs, $ofs + $len, sub { $_[0]->make_current ($tab) } ];
$ofs += $len + 1;
}
$self->{tabofs} = \@ofs;
$self->ROW_t (0, $text, 0, 0, $ncol);
$self->ROW_r (0, $rend, 0, 0, $ncol);
$self->want_refresh;
}
sub new_tab {
my ($self, @argv) = @_;
my $offset = $self->fheight;
# save a backlink to us, make sure tabbed is inactive
push @urxvt::TERM_INIT, sub {
my ($term) = @_;
$term->{parent} = $self;
for (0 .. urxvt::NUM_RESOURCES - 1) {
my $value = $self->{resource}[$_];
$term->resource ("+$_" => $value)
if defined $value;
}
$term->resource (perl_ext_2 => $term->resource ("perl_ext_2") . ",-tabbed");
};
push @urxvt::TERM_EXT, urxvt::ext::tabbed::tab2::;
my $term = new urxvt::term
$self->env, $urxvt::RXVTNAME,
-embed => $self->parent,
@argv,
;
}
sub configure {
my ($self) = @_;
my $tab = $self->{cur};
# this is an extremely dirty way to force a configurenotify, but who cares
$tab->XMoveResizeWindow (
$tab->parent,
0, $self->{tabheight} + 1,
$self->width, $self->height + $self->fheight - $self->{tabheight}
);
$tab->XMoveResizeWindow (
$tab->parent,
0, $self->{tabheight},
$self->width, $self->height + $self->fheight - $self->{tabheight}
);
}
sub on_resize_all_windows {
my ($self, $width, $height) = @_;
1
}
sub copy_properties {
my ($self) = @_;
my $tab = $self->{cur};
my $wm_normal_hints = $self->XInternAtom ("WM_NORMAL_HINTS");
my $current = delete $self->{current_properties};
# pass 1: copy over properties different or nonexisting
for my $atom ($tab->XListProperties ($tab->parent)) {
my ($type, $format, $items) = $self->XGetWindowProperty ($tab->parent, $atom);
# fix up size hints
if ($atom == $wm_normal_hints) {
my (@hints) = unpack "l!*", $items;
$hints[$_] += $self->{tabheight} for (4, 6, 16);
$items = pack "l!*", @hints;
}
my $cur = delete $current->{$atom};
# update if changed, we assume empty items and zero type and format will not happen
$self->XChangeProperty ($self->parent, $atom, $type, $format, $items)
if $cur->[0] != $type or $cur->[1] != $format or $cur->[2] ne $items;
$self->{current_properties}{$atom} = [$type, $format, $items];
}
# pass 2, delete all extraneous properties
$self->XDeleteProperty ($self->parent, $_) for keys %$current;
}
sub make_current {
my ($self, $tab) = @_;
if (my $cur = $self->{cur}) {
delete $cur->{activity};
$cur->XUnmapWindow ($cur->parent) if $cur->mapped;
$cur->focus_out;
}
$self->{cur} = $tab;
$self->configure;
$self->copy_properties;
$tab->focus_out; # just in case, should be a nop
$tab->focus_in if $self->focus;
$tab->XMapWindow ($tab->parent);
delete $tab->{activity};
$self->refresh;
()
}
sub on_focus_in {
my ($self, $event) = @_;
$self->{cur}->focus_in;
()
}
sub on_focus_out {
my ($self, $event) = @_;
$self->{cur}->focus_out;
()
}
sub on_key_press {
my ($self, $event) = @_;
$self->{cur}->key_press ($event->{state}, $event->{keycode}, $event->{time});
1
}
sub on_key_release {
my ($self, $event) = @_;
$self->{cur}->key_release ($event->{state}, $event->{keycode}, $event->{time});
1
}
sub on_button_press {
1
}
sub on_button_release {
my ($self, $event) = @_;
if ($event->{row} == 0) {
for my $button (@{ $self->{tabofs} }) {
$button->[2]->($self, $event)
if $event->{col} >= $button->[0]
&& $event->{col} < $button->[1];
}
}
1
}
sub on_motion_notify {
1
}
sub on_init {
my ($self) = @_;
$self->{resource} = [map $self->resource ("+$_"), 0 .. urxvt::NUM_RESOURCES - 1];
$self->resource (int_bwidth => 0);
$self->resource (name => "URxvt.tabbed");
$self->resource (pty_fd => -1);
$self->option ($urxvt::OPTION{scrollBar}, 0);
()
}
sub on_start {
my ($self) = @_;
#$self->{tabheight} = $self->int_bwidth + $self->fheight + $self->lineSpace;
$self->{tabheight} = 0;
# moved to on_start
my $fg = $self->x_resource ("tabbar-fg");
my $bg = $self->x_resource ("tabbar-bg");
my $tabfg = $self->x_resource ("tab-fg");
my $tabbg = $self->x_resource ("tab-bg");
defined $fg or $fg = 7; # white
defined $bg or $bg = 4; # blue
defined $tabfg or $tabfg = 0; # black
defined $tabbg or $tabbg = 7; # white
$self->{rs_tabbar} = urxvt::SET_COLOR (urxvt::DEFAULT_RSTYLE, $fg + 2, $bg + 2);
$self->{rs_tab} = urxvt::SET_COLOR (urxvt::DEFAULT_RSTYLE, $tabfg + 2, $tabbg + 2);
$self->cmd_parse ("\033[?25l");
my @argv = $self->argv;
do {
shift @argv;
} while @argv && $argv[0] ne "-e";
$self->new_tab (@argv);
()
}
sub on_configure_notify {
my ($self, $event) = @_;
$self->configure;
$self->refresh;
()
}
sub on_wm_delete_window {
my ($self) = @_;
$_->destroy for @{ $self->{tabs} };
1
}
sub tab_start {
my ($self, $tab) = @_;
$tab->XChangeInput ($tab->parent, urxvt::PropertyChangeMask);
push @{ $self->{tabs} }, $tab;
# show tabs when there are more than one tab
if(scalar(@{$self->{tabs}}) > 1) {
$self->{tabheight} = $self->int_bwidth + $self->fheight + $self->lineSpace;
}
# $tab->{name} ||= scalar @{ $self->{tabs} };
$self->make_current ($tab);
()
}
sub tab_destroy {
my ($self, $tab) = @_;
$self->{tabs} = [ grep $_ != $tab, @{ $self->{tabs} } ];
# hide tabs when only one remains
if (scalar(@{$self->{tabs}}) < 2) {
$self->{tabheight} = 0;
}
if (@{ $self->{tabs} }) {
if ($self->{cur} == $tab) {
delete $self->{cur};
$self->make_current ($self->{tabs}[-1]);
} else {
$self->refresh;
}
} else {
# delay destruction a tiny bit
$self->{destroy} = urxvt::iw->new->start->cb (sub { $self->destroy });
}
()
}
sub tab_key_press {
my ($self, $tab, $event, $keysym, $str) = @_;
if ($event->{state} & urxvt::ShiftMask) {
if ($keysym == 0xff51 || $keysym == 0xff53) {
my ($idx) = grep $self->{tabs}[$_] == $tab, 0 .. $#{ $self->{tabs} };
--$idx if $keysym == 0xff51;
++$idx if $keysym == 0xff53;
$self->make_current ($self->{tabs}[$idx % @{ $self->{tabs}}]);
return 1;
} elsif ($keysym == 0xff54) {
$self->new_tab;
return 1;
}
}
elsif ($event->{state} & urxvt::ControlMask) {
if ($keysym == 0xff51 || $keysym == 0xff53) {
my ($idx1) = grep $self->{tabs}[$_] == $tab, 0 .. $#{ $self->{tabs} };
my $idx2 = ($idx1 + ($keysym == 0xff51 ? -1 : +1)) % @{ $self->{tabs} };
($self->{tabs}[$idx1], $self->{tabs}[$idx2]) =
($self->{tabs}[$idx2], $self->{tabs}[$idx1]);
$self->make_current ($self->{tabs}[$idx2]);
return 1;
}
}
()
}
sub tab_property_notify {
my ($self, $tab, $event) = @_;
$self->copy_properties
if $event->{window} == $tab->parent;
()
}
sub tab_activity {
my ($self, $tab) = @_;
$self->refresh;
}
package urxvt::ext::tabbed::tab2;
# helper extension implementing the subwindows of a tabbed terminal.
# simply proxies all interesting calls back to the tabbed class.
{
for my $hook qw(start destroy key_press property_notify) {
eval qq{
sub on_$hook {
my \$parent = \$_[0]{term}{parent}
or return;
\$parent->tab_$hook (\@_)
}
};
die if $@;
}
}
sub on_add_lines {
$_[0]->{activity}++
or $_[0]{term}{parent}->tab_activity ($_[0]);
()
}-- edit: marked as [solved] since fix is provided in last post
Last edited by benob (2010-09-07 08:06:37)
Offline
The only thing I can think of is that the bottom line might not be tall enough for a character, so it is left blank.
Offline
When I run "urxvt -pe tabbed", the bottom line of the terminal stays blank. Can anyone confirm this bug?
Yes I have the same problem. Have you ever been able to solve this?
greetz
alex
Offline
The fix is in the code I provided. I also made a pastebin of it: http://pastebin.com/ztVUy7NN (it also hides the tab bar when there is only one tab, and changes the colors)
Here is the specific bit of code that fixes the extra line problem:
diff /usr/lib/urxvt/perl/tabbed urxvt.tabbed
...
84c90
< $self->width, $self->height - $self->{tabheight}
---
> $self->width, $self->height + $self->fheight - $self->{tabheight}
89c95
< $self->width, $self->height - $self->{tabheight}
---
> $self->width, $self->height + $self->fheight - $self->{tabheight}
...Offline
This fix works perfectly (although I did apply those small changes manually only).
Thank you.
Last edited by bernarcher (2010-09-07 07:31:49)
To know or not to know ...
... the questions remain forever.
Offline
Thx that fixed the issue. But i don't understand where this come from.
If I download the original urxvt source and apply the color patch, I don't
have the issue.
Offline
(or install in the right place and set Xdefault accordingly)
Hello,
can you give me a few instructions, how to install your script?
Thank you!
Last edited by ratzfatz (2011-11-08 17:37:44)
The common language in modern science is broken english ![]()
Offline