mirror of
https://github.com/gryf/tabbedalt.git
synced 2025-12-17 11:30:31 +01:00
Added ability to confogure window close confirmation.
This commit is contained in:
57
README.rst
57
README.rst
@@ -8,9 +8,9 @@ terminal emulator
|
|||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
||||||
* Possibility to add named tabs, through the X resources, which represents its
|
* Possibility to add named tabs, through the X resources, which run specified
|
||||||
*class*. Without any configuration only default shell *class* is available
|
command or another shell (zsh/fish/ash/csh/ksh…). Without any configuration
|
||||||
under default (``Shift+Down``) shortcut.
|
only default shell is available under default (``Shift+Down``) shortcut.
|
||||||
|
|
||||||
.. image:: /screens/tabbed.png
|
.. image:: /screens/tabbed.png
|
||||||
:alt: Named tabs
|
:alt: Named tabs
|
||||||
@@ -31,6 +31,8 @@ Features
|
|||||||
option. See below for examples.
|
option. See below for examples.
|
||||||
* Autohide tab when there is only one tab at the moment.
|
* Autohide tab when there is only one tab at the moment.
|
||||||
* Ability to assign hotkey to jump to last tab.
|
* Ability to assign hotkey to jump to last tab.
|
||||||
|
* Configurable confirm dialog for closing urxvt window, when there is more than
|
||||||
|
one tab opened or there is an process still running.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
@@ -247,6 +249,42 @@ still a way for selecting 10th tab, i.e.::
|
|||||||
In the example above, there are mapping for jump to tabs 1 - 12 using function
|
In the example above, there are mapping for jump to tabs 1 - 12 using function
|
||||||
keys, and `Control+0` to jump whatever last tab is.
|
keys, and `Control+0` to jump whatever last tab is.
|
||||||
|
|
||||||
|
Confirm closing window
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
When working with tabs, sometimes user accidentally could close the window, and
|
||||||
|
loose all the applications run on the tabs. There might be multiple tabs open,
|
||||||
|
or just one with running process on it (i.e. some editor), where closing window
|
||||||
|
by accident could result in data loss. To prevent this, there are couple of
|
||||||
|
resources to be set. First one, disabled by default is::
|
||||||
|
|
||||||
|
URxvt.tabbedalt.confirm-quit: false
|
||||||
|
|
||||||
|
When set to ``true`` it will execute a message program defined in
|
||||||
|
``confirm-program`` resource. It might be whatever X program, which can accept
|
||||||
|
text as an argument, and can provide dialog which:
|
||||||
|
|
||||||
|
- have two buttons (i.e. yes/no, ok/cancel) where first will exit dialog with 0
|
||||||
|
exit code and the latter will exit with whatever other number,
|
||||||
|
- destroying the dialog also emit exit code higher than 0.
|
||||||
|
|
||||||
|
So, for example standard `xmessage`_ can be used::
|
||||||
|
|
||||||
|
URxvt.tabbedalt.confirm-program: xmessage -buttons ok:0,cancel:1
|
||||||
|
|
||||||
|
or `zenity`_::
|
||||||
|
|
||||||
|
URxvt.tabbedalt.confirm-program: zenity --question --title 'Close window' --text
|
||||||
|
|
||||||
|
or `kdialog`_::
|
||||||
|
|
||||||
|
URxvt.tabbedalt.confirm-program: kdialog --title 'Close window' --yesno
|
||||||
|
|
||||||
|
or… any other dialog programs which fulfill the above criteria.
|
||||||
|
|
||||||
|
Note, that ``confirm-program`` resource have no default value and you'll need
|
||||||
|
to configure it alongside with the ``confirm-quit``, otherwise ``confirm-quit``
|
||||||
|
will have no effect.
|
||||||
|
|
||||||
Creating specific commands/shells
|
Creating specific commands/shells
|
||||||
---------------------------------
|
---------------------------------
|
||||||
@@ -260,14 +298,14 @@ Let's assume, that one want to add three kind of custom shells:
|
|||||||
A way to do this is to associate keystroke for it in ``.Xdefaults`` using
|
A way to do this is to associate keystroke for it in ``.Xdefaults`` using
|
||||||
urxvts ``keysym`` option, and the actions described above::
|
urxvts ``keysym`` option, and the actions described above::
|
||||||
|
|
||||||
URxvt.keysym.Control-Shift-N: tabbedalt.new_tab:shell
|
URxvt.keysym.Control-Shift-N: tabbedalt:new_tab:shell
|
||||||
URxvt.keysym.Control-Shift-R: tabbedalt.new_tab:root:su -
|
URxvt.keysym.Control-Shift-R: tabbedalt:new_tab:root:su -
|
||||||
URxvt.keysym.Control-Shift-M: tabbedalt.new_tab:mc:mc
|
URxvt.keysym.Control-Shift-M: tabbedalt:new_tab:mc:mc
|
||||||
|
|
||||||
Resource values are colon separated values, which are in order:
|
Resource values are colon separated values, which are in order:
|
||||||
|
|
||||||
* **plugin name**, which in case of this very plugin would be always
|
* **plugin name:command**, which in this case of creating new tab will be
|
||||||
``tabbedalt``.
|
``tabbedalt:new_tab``.
|
||||||
* **title of the tab**, it could be anything but the colon.
|
* **title of the tab**, it could be anything but the colon.
|
||||||
* **optional command**. If omitted, default shell will be launched.
|
* **optional command**. If omitted, default shell will be launched.
|
||||||
|
|
||||||
@@ -282,3 +320,6 @@ feature was taken from `stepb`_ tabbedx repository.
|
|||||||
.. _activity indicator: http://mina86.com/2009/05/16/tabbed-urxvt-extension/
|
.. _activity indicator: http://mina86.com/2009/05/16/tabbed-urxvt-extension/
|
||||||
.. _stepb: http://github.com/stepb/urxvt-tabbedex
|
.. _stepb: http://github.com/stepb/urxvt-tabbedex
|
||||||
.. _tabbedex: https://github.com/mina86/urxvt-tabbedex
|
.. _tabbedex: https://github.com/mina86/urxvt-tabbedex
|
||||||
|
.. _xmessage: https://gitlab.freedesktop.org/xorg/app/xmessage
|
||||||
|
.. _zenity: https://wiki.gnome.org/Projects/Zenity
|
||||||
|
.. _kdialog: https://develop.kde.org/docs/administration/kdialog
|
||||||
|
|||||||
62
tabbedalt
62
tabbedalt
@@ -148,6 +148,10 @@
|
|||||||
#
|
#
|
||||||
# 2022-09-18 14:26:00
|
# 2022-09-18 14:26:00
|
||||||
# - Add workaround for font flickering
|
# - Add workaround for font flickering
|
||||||
|
#
|
||||||
|
# 2023-10-24 21:14:56
|
||||||
|
# - Added confirmation when closing window when there is more than one tab or
|
||||||
|
# there is a process still running.
|
||||||
|
|
||||||
use Scalar::Util;
|
use Scalar::Util;
|
||||||
|
|
||||||
@@ -467,12 +471,18 @@ sub _key_event {
|
|||||||
|
|
||||||
_on focus_in => sub {
|
_on focus_in => sub {
|
||||||
my ($self, $event) = @_;
|
my ($self, $event) = @_;
|
||||||
|
if (defined($self->{is_being_destroyed})) {
|
||||||
|
return
|
||||||
|
}
|
||||||
$self->{cur}->focus_in;
|
$self->{cur}->focus_in;
|
||||||
()
|
()
|
||||||
};
|
};
|
||||||
|
|
||||||
_on focus_out => sub {
|
_on focus_out => sub {
|
||||||
my ($self, $event) = @_;
|
my ($self, $event) = @_;
|
||||||
|
if (defined($self->{is_being_destroyed})) {
|
||||||
|
return
|
||||||
|
}
|
||||||
$self->{cur}->focus_out;
|
$self->{cur}->focus_out;
|
||||||
()
|
()
|
||||||
};
|
};
|
||||||
@@ -551,6 +561,8 @@ sub init {
|
|||||||
$self->{autohide} = $self->x_resource_boolean('autohide');
|
$self->{autohide} = $self->x_resource_boolean('autohide');
|
||||||
$self->{zero_jump_last} = $self->x_resource_boolean('zero-jump-last');
|
$self->{zero_jump_last} = $self->x_resource_boolean('zero-jump-last');
|
||||||
$self->{stop_flickering} = $self->x_resource_boolean('stop-flickering');
|
$self->{stop_flickering} = $self->x_resource_boolean('stop-flickering');
|
||||||
|
$self->{confirm_quit} = $self->x_resource_boolean('confirm-quit');
|
||||||
|
$self->{confirm_program} = $self->x_resource('confirm-program');
|
||||||
|
|
||||||
my $timeouts = $self->x_resource ("tabbar-timeouts");
|
my $timeouts = $self->x_resource ("tabbar-timeouts");
|
||||||
$timeouts = '16:.:8:::4:+' unless defined $timeouts;
|
$timeouts = '16:.:8:::4:+' unless defined $timeouts;
|
||||||
@@ -614,7 +626,55 @@ _on configure_notify => sub {
|
|||||||
_on wm_delete_window => sub {
|
_on wm_delete_window => sub {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
$_->destroy for @{ $self->{tabs} };
|
if ($self->{confirm_quit} and $self->{confirm_program}) {
|
||||||
|
my $tab_count = @{ $self->{tabs} };
|
||||||
|
my $subp_count = 0;
|
||||||
|
my @subprocesses = split(/\n/, `ps --ppid $$ -o pid=,cmd=`);
|
||||||
|
my %process_to_skip = ( "bash"=>1, "zsh"=>1, "ps"=>1, "fish"=>1, "sh"=>1 );
|
||||||
|
|
||||||
|
foreach my $line (@subprocesses) {
|
||||||
|
chomp $line;
|
||||||
|
my @split_line = split(/ /, $line);
|
||||||
|
my $pid = @split_line[0];
|
||||||
|
my $proc_name = @split_line[1];
|
||||||
|
chomp $proc_name;
|
||||||
|
if (!exists $process_to_skip{$proc_name}) {
|
||||||
|
$subp_count = $subp_count + 1;
|
||||||
|
} else {
|
||||||
|
$subp_count = $subp_count + `ps --ppid $pid -o pid= | wc -l`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($tab_count > 1 or $subp_count > 0) {
|
||||||
|
my $msg = "";
|
||||||
|
$msg = "There are $tab_count tabs opened" if ($tab_count > 1);
|
||||||
|
|
||||||
|
if ($subp_count > 0) {
|
||||||
|
if (! $msg) {
|
||||||
|
$msg = "There is $subp_count active processes running.";
|
||||||
|
$msg = "$msg Are you sure you want to close urxvt?";
|
||||||
|
} else {
|
||||||
|
$msg = "$msg and there is $subp_count active processes running.";
|
||||||
|
$msg = "$msg Are you sure you want to close urxvt?";
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$msg = "$msg. Are you sure you want to close urxvt?";
|
||||||
|
}
|
||||||
|
|
||||||
|
`$self->{confirm_program} '$msg'`;
|
||||||
|
|
||||||
|
if ($? == 0) {
|
||||||
|
$self->{is_being_destroyed} = 1;
|
||||||
|
# stop the timers, as we changed focus
|
||||||
|
$self->{timer}->stop();
|
||||||
|
$_->destroy for @{ $self->{tabs} };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_->destroy for @{ $self->{tabs} };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$_->destroy for @{ $self->{tabs} };
|
||||||
|
}
|
||||||
|
|
||||||
1
|
1
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user