1
0
mirror of https://github.com/gryf/tabbedalt.git synced 2026-04-29 10:14:11 +02:00

Compare commits

...

4 Commits

Author SHA1 Message Date
gryf f57e535e64 Added more memory optimizations 2026-04-21 18:44:43 +02:00
gryf b811ca58f6 Removed redundant sections 2026-04-21 18:44:08 +02:00
gryf 2cede3b996 Fix memory leaks caused by not freed resources from X properites 2026-04-21 16:35:27 +02:00
gryf 2ba623a811 Fix wrong shortcut in README 2026-04-21 16:28:46 +02:00
2 changed files with 67 additions and 37 deletions
+4 -32
View File
@@ -183,7 +183,7 @@ several keysyms mapped to the actions:
* ``Shift-Up``: ``rename_tab`` - for tab title renaming
* ``Shift-Left``: ``prev_tab`` - for jumping to previous tab
* ``Shift-Right``: ``next_tab`` - for jumping to next tab
* ``Shift-Left``: ``move_tab_left`` - for moving tab to the left
* ``Control-Left``: ``move_tab_left`` - for moving tab to the left
* ``Control-Right``: ``move_tab_right`` - for moving tab to the right
* ``Control-1..0``: ``jump_to_tab`` - for quickly jumping into first tenth tabs
@@ -200,9 +200,11 @@ It might be wise to define own shortcuts before disabling default keys.
``tab-command``, for example::
URxvt.keysym.Control-t: tabbedalt:new_tab:htop:htop
URxvt.keysym.Control-Shift-R: tabbedalt:new_tab:root:sudo su -
where pressing control+t it will run new tab with title ``htop`` and command
``htop``.
``htop``, while pressing control+shift+r will create tab with ``root``
title and run ``sudo su -`` inside.
Both title and command may be omitted. If so, default title ``shell`` will
be used in absence of title, and default shell will be run on missing
@@ -296,36 +298,6 @@ or `kdialog`_::
or… any other dialog programs which fulfill the above criteria.
Creating specific commands/shells
---------------------------------
Let's assume, that one want to add three kind of custom shells:
* simple one (default shell in the system),
* midnight commander,
* root (namely - su command)
A way to do this is to associate keystroke for it in ``.Xdefaults`` using
urxvts ``keysym`` option, and the actions described above::
URxvt.keysym.Control-Shift-N: tabbedalt:new_tab:shell
URxvt.keysym.Control-Shift-R: tabbedalt:new_tab:root:su -
URxvt.keysym.Control-Shift-M: tabbedalt:new_tab:mc:mc
Resource values are colon separated values, which are in order:
* **plugin name:command**, which in this case of creating new tab will be
``tabbedalt:new_tab``.
* **title of the tab**, it could be anything but the colon.
* **optional command**. If omitted, default shell will be launched.
Renaming tabs
-------------
On runtime, tabs can be renamed using (by default) ``Shift+Up`` - now you can
type name for the tab. ``Return`` accept change, ``ESC`` cancels it. This
feature was taken from `stepb`_ tabbedx repository.
.. _urxvt-unicode: http://software.schmorp.de/pkg/rxvt-unicode.html
.. _activity indicator: http://mina86.com/2009/05/16/tabbed-urxvt-extension/
.. _stepb: http://github.com/stepb/urxvt-tabbedex
+63 -5
View File
@@ -162,6 +162,16 @@
# 2024-12-10 18:30:22
# - Fix an issue with requesting closing terminal, which appear to be a
# single instance
#
# 2026-04-21 16:29:49
# - Fix small but constant memory consumption, which over time eventually will
# cause urxvt to consume huge amount of memory
#
# 2026-04-21 18:34:16
# - Make some more optimization on memory usage - remove data from destroyed
# tab and disable its hooks
# - update tab property notifications, don't update it too often, clean up X
# properties variables after use, update only changed X properties
use Scalar::Util;
@@ -266,14 +276,16 @@ sub refresh {
my ($self) = @_;
my $tabs_no = (@{$self->{tabs}});
my $old_tabheight = $self->{tabheight} // 0;
if ($self->{autohide} && $tabs_no == 1 &&
! $self->{cur}->{is_being_renamed}) {
$self->{tabheight} = 0;
$self->configure;
$self->copy_properties;
return;
} else {
$self->{tabheight} = $self->{_tabheight};
}
if ($old_tabheight != $self->{tabheight}) {
$self->configure;
$self->copy_properties;
}
@@ -283,6 +295,8 @@ sub refresh {
my $text = " " x $ncol;
my $rend = [($self->{rs_tabbar}) x $ncol];
undef $self->{tabofs};
my ($ofs, $idx, @ofs) = (0, 0);
if ($self->{new_button}) {
@@ -422,6 +436,9 @@ sub copy_properties {
if $cur->[0] != $type or $cur->[1] != $format or $cur->[2] ne $items;
$self->{current_properties}{$atom} = [$type, $format, $items];
undef $type;
undef $format;
undef $items;
}
# pass 2, delete all extraneous properties
@@ -744,6 +761,18 @@ sub tab_start {
sub tab_destroy {
my ($self, $tab) = @_;
# Disable hooks and remove data from tab
$tab->disable('line_update', 'key_press', 'property_notify', 'action', 'start', 'destroy');
delete $tab->{lastActivity};
delete $tab->{is_being_renamed};
delete $tab->{old_name};
delete $tab->{new_name};
delete $tab->{overlay};
delete $tab->{main};
delete $tab->{parent};
delete $tab->{'tabbedalt_main'};
delete $tab->{name};
$self->{tabs} = [ grep $_ != $tab, @{ $self->{tabs} } ];
if (@{ $self->{tabs} }) {
@@ -775,8 +804,37 @@ sub command {
sub tab_property_notify {
my ($self, $tab, $event) = @_;
$self->copy_properties
if $event->{window} == $tab->parent;
return () unless $event->{window} == $tab->parent;
return () unless $tab == $self->{cur};
# skip if called too often (within 0.1s)
my $now = urxvt::NOW;
my $last = $self->{last_property_update} // 0;
if ($now - $last < 0.1) {
return ();
}
$self->{last_property_update} = $now;
# update only the changed property instead of all properties
my $atom = $event->{atom};
my ($type, $format, $items) = $self->XGetWindowProperty ($tab->parent, $atom);
my $wm_normal_hints = $self->XInternAtom ("WM_NORMAL_HINTS");
# 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;
}
$self->XChangeProperty ($self->parent, $atom, $type, $format, $items);
$self->{current_properties}{$atom} = [$type, $format, $items];
# free memory from X properties
undef $type;
undef $format;
undef $items;
()
}