summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authornemaeon2015-10-27 19:16:04 -0400
committernemaeon2015-10-27 19:16:04 -0400
commit602139fc2b3f016ea2ea0530e14670f6192f2bad (patch)
treea0ad0bd0390d3c3ea48faa808ea36048e8f64cf6
parent2d84dfa715f84ea97e9a76cc0ddb12a72fdd3dce (diff)
downloadaur-602139fc2b3f016ea2ea0530e14670f6192f2bad.tar.gz
Update to rtorrent 0.9.6
-rw-r--r--.SRCINFO14
-rwxr-xr-xPKGBUILD8
-rwxr-xr-xrtorrent-0.9.6_color.patch446
-rwxr-xr-xrtorrent-0.9.6_vi_keybinding_tjwoosta.patch172
4 files changed, 629 insertions, 11 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 3de4ecab92eb..05999c368d96 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,22 +1,22 @@
pkgbase = rtorrent-vi-color
pkgdesc = Ncurses BitTorrent client based on libTorrent with vi like keybindings and color patch.
- pkgver = 0.9.4
- pkgrel = 4
+ pkgver = 0.9.6
+ pkgrel = 2
url = http://libtorrent.rakshasa.no
install = rtorrent-vi-color.install
arch = i686
arch = x86_64
license = GPL
depends = curl
- depends = libtorrent>=0.13.5
+ depends = libtorrent>=0.13.6
depends = xmlrpc-c
depends = libsigc++
provides = rtorrent
conflicts = rtorrent
- source = rtorrent-vi-color-0.9.4.tar.gz::https://github.com/rakshasa/rtorrent/archive/0.9.4.tar.gz
- source = rtorrent-0.9.4_vi_keybinding_tjwoosta.patch
- source = rtorrent-0.9.4_color.patch
- sha1sums = c1f0b27425f6b025db550cf5ce1997a16af6ff7b
+ source = rtorrent-vi-color-0.9.6.tar.gz::https://github.com/rakshasa/rtorrent/archive/0.9.6.tar.gz
+ source = rtorrent-0.9.6_vi_keybinding_tjwoosta.patch
+ source = rtorrent-0.9.6_color.patch
+ sha1sums = 27505081254618077c291eb1ee36bfb41f974834
sha1sums = d35b53be6d1d5686c8a66ea821154e095e7a1556
sha1sums = 78429b5cf5976270dc1a55d8dc0ef4644675512b
diff --git a/PKGBUILD b/PKGBUILD
index 24363f067212..77a82a0c8080 100755
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -8,20 +8,20 @@
pkgname="rtorrent-vi-color"
_pkgname="rtorrent"
-pkgver=0.9.4
-pkgrel=4
+pkgver=0.9.6
+pkgrel=2
pkgdesc='Ncurses BitTorrent client based on libTorrent with vi like keybindings and color patch.'
url="http://libtorrent.rakshasa.no"
arch=('i686' 'x86_64')
license=('GPL')
-depends=("curl" "libtorrent>=0.13.4" "xmlrpc-c" "libsigc++")
+depends=("curl" "libtorrent>=0.13.6" "xmlrpc-c" "libsigc++")
conflicts=("${_pkgname}")
provides=("${_pkgname}")
install="${pkgname}.install"
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/rakshasa/${_pkgname}/archive/${pkgver}.tar.gz"
"${_pkgname}-${pkgver}_vi_keybinding_tjwoosta.patch"
"${_pkgname}-${pkgver}_color.patch")
-sha1sums=('c1f0b27425f6b025db550cf5ce1997a16af6ff7b'
+sha1sums=('27505081254618077c291eb1ee36bfb41f974834'
'd35b53be6d1d5686c8a66ea821154e095e7a1556'
'78429b5cf5976270dc1a55d8dc0ef4644675512b')
diff --git a/rtorrent-0.9.6_color.patch b/rtorrent-0.9.6_color.patch
new file mode 100755
index 000000000000..9595b83fafe0
--- /dev/null
+++ b/rtorrent-0.9.6_color.patch
@@ -0,0 +1,446 @@
+diff --git a/src/command_network.cc b/src/command_network.cc
+index c445c38..24ad5c0 100644
+--- a/src/command_network.cc
++++ b/src/command_network.cc
+@@ -241,6 +241,26 @@ initialize_command_network() {
+ CMD2_ANY ("strings.connection_type", tr1::bind(&torrent::option_list_strings, torrent::OPTION_CONNECTION_TYPE));
+ CMD2_ANY ("strings.encryption", tr1::bind(&torrent::option_list_strings, torrent::OPTION_ENCRYPTION));
+
++ CMD2_ANY ("colors.color_inactive_fg", tr1::bind(&ui::Root::get_color_inactive_fg, control->ui()));
++ CMD2_ANY_VALUE_V ("colors.color_inactive_fg.set", tr1::bind(&ui::Root::set_color_inactive_fg, control->ui(), tr1::placeholders::_2));
++ CMD2_ANY ("colors.color_inactive_bg", tr1::bind(&ui::Root::get_color_inactive_bg, control->ui()));
++ CMD2_ANY_VALUE_V ("colors.color_inactive_bg.set", tr1::bind(&ui::Root::set_color_inactive_bg, control->ui(), tr1::placeholders::_2));
++
++ CMD2_ANY ("colors.color_dead_fg", tr1::bind(&ui::Root::get_color_dead_fg, control->ui()));
++ CMD2_ANY_VALUE_V ("colors.color_dead_fg.set", tr1::bind(&ui::Root::set_color_dead_fg, control->ui(), tr1::placeholders::_2));
++ CMD2_ANY ("colors.color_dead_bg", tr1::bind(&ui::Root::get_color_dead_bg, control->ui()));
++ CMD2_ANY_VALUE_V ("colors.color_dead_bg.set", tr1::bind(&ui::Root::set_color_dead_bg, control->ui(), tr1::placeholders::_2));
++
++ CMD2_ANY ("colors.color_active_fg", tr1::bind(&ui::Root::get_color_active_fg, control->ui()));
++ CMD2_ANY_VALUE_V ("colors.color_active_fg.set", tr1::bind(&ui::Root::set_color_active_fg, control->ui(), tr1::placeholders::_2));
++ CMD2_ANY ("colors.color_active_bg", tr1::bind(&ui::Root::get_color_active_bg, control->ui()));
++ CMD2_ANY_VALUE_V ("colors.color_active_bg.set", tr1::bind(&ui::Root::set_color_active_bg, control->ui(), tr1::placeholders::_2));
++
++ CMD2_ANY ("colors.color_finished_fg", tr1::bind(&ui::Root::get_color_finished_fg, control->ui()));
++ CMD2_ANY_VALUE_V ("colors.color_finished_fg.set", tr1::bind(&ui::Root::set_color_finished_fg, control->ui(), tr1::placeholders::_2));
++ CMD2_ANY ("colors.color_finished_bg", tr1::bind(&ui::Root::get_color_finished_bg, control->ui()));
++ CMD2_ANY_VALUE_V ("colors.color_finished_bg.set", tr1::bind(&ui::Root::set_color_finished_bg, control->ui(), tr1::placeholders::_2));
++
+ // CMD2_ANY_STRING ("encoding_list", tr1::bind(&apply_encoding_list, tr1::placeholders::_2));
+ CMD2_ANY_STRING ("encoding.add", tr1::bind(&apply_encoding_list, tr1::placeholders::_2));
+
+diff --git a/src/display/canvas.cc b/src/display/canvas.cc
+index 31db4ad..255e7c3 100644
+--- a/src/display/canvas.cc
++++ b/src/display/canvas.cc
+@@ -99,6 +99,12 @@ Canvas::initialize() {
+ m_isInitialized = true;
+
+ initscr();
++ start_color();
++ use_default_colors();
++ init_pair(4, -1, -1);
++ init_pair(3, -1, -1);
++ init_pair(2, -1, -1);
++ init_pair(1, -1, -1);
+ raw();
+ noecho();
+ nodelay(stdscr, TRUE);
+diff --git a/src/display/window_download_list.cc b/src/display/window_download_list.cc
+index ead4ddd..ffd79c9 100644
+--- a/src/display/window_download_list.cc
++++ b/src/display/window_download_list.cc
+@@ -37,6 +37,7 @@
+ #include "config.h"
+
+ #include <rak/algorithm.h>
++#include <torrent/rate.h>
+
+ #include "core/download.h"
+ #include "core/view.h"
+@@ -104,9 +105,41 @@ WindowDownloadList::redraw() {
+ char buffer[m_canvas->width() + 1];
+ char* last = buffer + m_canvas->width() - 2 + 1;
+
++ /*
++ There are four states where colors are applied:
++ 1 inactive # If inactive, e.g. user stopped down/upload
++ 2 dead # If active but no down/upload
++ 3 active # If active and download
++ 4 finished # If finished
++ */
++
+ print_download_title(buffer, last, *range.first);
+- m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
+-
++ m_canvas->print(0, pos, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
++ if( (*range.first)->is_done() ) {
++ if( (*range.first)->download()->info()->up_rate()->rate() != 0 ) {
++ m_canvas->set_attr(0, pos, m_canvas->width()-1, A_BOLD, 4); // Finished and uploading
++ } else {
++ m_canvas->set_attr(0, pos, m_canvas->width()-1, A_NORMAL, 4); // Finished
++ }
++ } else if( (*range.first)->is_active() ) {
++ if( (*range.first)->download()->info()->down_rate()->rate() != 0 ) {
++ if( (*range.first)->download()->info()->up_rate()->rate() != 0 ) {
++ m_canvas->set_attr(0, pos, m_canvas->width()-1, A_BOLD, 3); // Active and uploading
++ } else {
++ m_canvas->set_attr(0, pos, m_canvas->width()-1, A_NORMAL, 3); // Active
++ }
++ } else {
++ if( (*range.first)->download()->info()->up_rate()->rate() != 0 ) {
++ m_canvas->set_attr(0, pos, m_canvas->width()-1, A_BOLD, 2); // Dead but still uploading
++ } else {
++ m_canvas->set_attr(0, pos, m_canvas->width()-1, A_NORMAL, 2); // Dead
++ }
++ }
++ } else {
++ m_canvas->set_attr(0, pos, m_canvas->width()-1, A_NORMAL, 1); // Inactive
++ }
++ pos++;
++
+ print_download_info(buffer, last, *range.first);
+ m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
+
+@@ -114,7 +147,83 @@ WindowDownloadList::redraw() {
+ m_canvas->print(0, pos++, "%c %s", range.first == m_view->focus() ? '*' : ' ', buffer);
+
+ ++range.first;
+- }
++ }
++}
++
++// Inactive
++void
++WindowDownloadList::set_color_inactive_fg(int64_t color) {
++ short fg, bg;
++ pair_content(1, &fg, &bg);
++ if( color < 0 ) color = -1;
++ color = color % 8;
++ init_pair(1, (short)color, bg);
++}
++
++void
++WindowDownloadList::set_color_inactive_bg(int64_t color) {
++ short fg, bg;
++ pair_content(1, &fg, &bg);
++ if( color < 0 ) color = -1;
++ color = color % 8;
++ init_pair(1, fg, (short)color);
++}
++
++// Dead
++void
++WindowDownloadList::set_color_dead_fg(int64_t color) {
++ short fg, bg;
++ pair_content(2, &fg, &bg);
++ if( color < 0 ) color = -1;
++ color = color % 8;
++ init_pair(2, (short)color, bg);
++}
++
++void
++WindowDownloadList::set_color_dead_bg(int64_t color) {
++ short fg, bg;
++ pair_content(2, &fg, &bg);
++ if( color < 0 ) color = -1;
++ color = color % 8;
++ init_pair(2, fg, (short)color);
++}
++
++// Active
++void
++WindowDownloadList::set_color_active_fg(int64_t color) {
++ short fg, bg;
++ pair_content(3, &fg, &bg);
++ if( color < 0 ) color = -1;
++ color = color % 8;
++ init_pair(3, (short)color, bg);
++}
++
++void
++WindowDownloadList::set_color_active_bg(int64_t color) {
++ short fg, bg;
++ pair_content(3, &fg, &bg);
++ if( color < 0 ) color = -1;
++ color = color % 8;
++ init_pair(3, fg, (short)color);
++}
++
++// Finished
++void
++WindowDownloadList::set_color_finished_fg(int64_t color) {
++ short fg, bg;
++ pair_content(4, &fg, &bg);
++ if( color < 0 ) color = -1;
++ color = color % 8;
++ init_pair(4, (short)color, bg);
++}
++
++void
++WindowDownloadList::set_color_finished_bg(int64_t color) {
++ short fg, bg;
++ pair_content(4, &fg, &bg);
++ if( color < 0 ) color = -1;
++ color = color % 8;
++ init_pair(4, fg, (short)color);
+ }
+
+ }
+diff --git a/src/display/window_download_list.h b/src/display/window_download_list.h
+index 8e15cac..4551a47 100644
+--- a/src/display/window_download_list.h
++++ b/src/display/window_download_list.h
+@@ -55,6 +55,15 @@ public:
+
+ void set_view(core::View* l);
+
++ void set_color_inactive_fg(int64_t color);
++ void set_color_inactive_bg(int64_t color);
++ void set_color_dead_fg(int64_t color);
++ void set_color_dead_bg(int64_t color);
++ void set_color_active_fg(int64_t color);
++ void set_color_active_bg(int64_t color);
++ void set_color_finished_fg(int64_t color);
++ void set_color_finished_bg(int64_t color);
++
+ private:
+ core::View* m_view;
+
+diff --git a/src/main.cc b/src/main.cc
+index 5e826bb..44faa21 100644
+--- a/src/main.cc
++++ b/src/main.cc
+@@ -388,6 +388,15 @@ main(int argc, char** argv) {
+ CMD2_REDIRECT ("ip", "network.local_address.set");
+ CMD2_REDIRECT ("port_range", "network.port_range.set");
+
++ CMD2_REDIRECT ("color_inactive_fg", "colors.color_inactive_fg.set");
++ CMD2_REDIRECT ("color_inactive_bg", "colors.color_inactive_bg.set");
++ CMD2_REDIRECT ("color_dead_fg", "colors.color_dead_fg.set");
++ CMD2_REDIRECT ("color_dead_bg", "colors.color_dead_bg.set");
++ CMD2_REDIRECT ("color_active_fg", "colors.color_active_fg.set");
++ CMD2_REDIRECT ("color_active_bg", "colors.color_active_bg.set");
++ CMD2_REDIRECT ("color_finished_fg", "colors.color_finished_fg.set");
++ CMD2_REDIRECT ("color_finished_bg", "colors.color_finished_bg.set");
++
+ CMD2_REDIRECT_GENERIC("dht", "dht.mode.set");
+ CMD2_REDIRECT_GENERIC("dht_port", "dht.port.set");
+
+diff --git a/src/ui/download_list.cc b/src/ui/download_list.cc
+index e3abc9a..7dc7469 100644
+--- a/src/ui/download_list.cc
++++ b/src/ui/download_list.cc
+@@ -136,6 +136,11 @@ DownloadList::unfocus_download(core::Download* d) {
+ current_view()->next_focus();
+ }
+
++display::WindowDownloadList*
++DownloadList::current_window_list() {
++ return dynamic_cast<ElementDownloadList*>(m_uiArray[DISPLAY_DOWNLOAD_LIST])->window();
++}
++
+ void
+ DownloadList::activate_display(Display displayType) {
+ if (!is_active())
+diff --git a/src/ui/download_list.h b/src/ui/download_list.h
+index 3712e36..7810f65 100644
+--- a/src/ui/download_list.h
++++ b/src/ui/download_list.h
+@@ -98,6 +98,7 @@ public:
+ void activate_display(Display d);
+
+ core::View* current_view();
++ display::WindowDownloadList* current_window_list();
+ void set_current_view(const std::string& name);
+
+ void slot_open_uri(slot_string s) { m_slot_open_uri = s; }
+diff --git a/src/ui/element_download_list.h b/src/ui/element_download_list.h
+index 20185b5..00ef880 100644
+--- a/src/ui/element_download_list.h
++++ b/src/ui/element_download_list.h
+@@ -60,6 +60,7 @@ public:
+ void disable();
+
+ core::View* view() { return m_view; }
++ WDownloadList* window() { return m_window; }
+ void set_view(core::View* l);
+
+ void receive_command(const char* cmd);
+diff --git a/src/ui/root.cc b/src/ui/root.cc
+index 981fcc2..2df0f5a 100644
+--- a/src/ui/root.cc
++++ b/src/ui/root.cc
+@@ -44,6 +44,7 @@
+
+ #include "core/manager.h"
+ #include "display/frame.h"
++#include "display/window_download_list.h"
+ #include "display/window_http_queue.h"
+ #include "display/window_title.h"
+ #include "display/window_input.h"
+@@ -65,7 +66,15 @@ Root::Root() :
+ m_windowTitle(NULL),
+ m_windowHttpQueue(NULL),
+ m_windowInput(NULL),
+- m_windowStatusbar(NULL) {
++ m_windowStatusbar(NULL),
++ color_inactive_fg(-1),
++ color_inactive_bg(-1),
++ color_dead_fg(-1),
++ color_dead_bg(-1),
++ color_active_fg(-1),
++ color_active_bg(-1),
++ color_finished_fg(-1),
++ color_finished_bg(-1) {
+ }
+
+ void
+@@ -97,6 +106,14 @@ Root::init(Control* c) {
+ setup_keys();
+
+ m_downloadList->activate(rootFrame->frame(1));
++ m_downloadList->current_window_list()->set_color_inactive_fg(color_inactive_fg);
++ m_downloadList->current_window_list()->set_color_inactive_bg(color_inactive_bg);
++ m_downloadList->current_window_list()->set_color_dead_fg(color_dead_fg);
++ m_downloadList->current_window_list()->set_color_dead_bg(color_dead_bg);
++ m_downloadList->current_window_list()->set_color_active_fg(color_active_fg);
++ m_downloadList->current_window_list()->set_color_active_bg(color_active_bg);
++ m_downloadList->current_window_list()->set_color_finished_fg(color_finished_fg);
++ m_downloadList->current_window_list()->set_color_finished_bg(color_finished_bg);
+ }
+
+ void
+@@ -272,4 +289,88 @@ Root::current_input() {
+ return m_windowInput->input();
+ }
+
++// Inactive
++int
++Root::get_color_inactive_fg() {
++ return color_inactive_fg;
++}
++
++void
++Root::set_color_inactive_fg(int64_t color) {
++ color_inactive_fg = color;
++}
++
++int
++Root::get_color_inactive_bg() {
++ return color_inactive_bg;
++}
++
++void
++Root::set_color_inactive_bg(int64_t color) {
++ color_inactive_bg = color;
++}
++
++// Dead
++int
++Root::get_color_dead_fg() {
++ return color_dead_fg;
++}
++
++void
++Root::set_color_dead_fg(int64_t color) {
++ color_dead_fg = color;
++}
++
++int
++Root::get_color_dead_bg() {
++ return color_dead_bg;
++}
++
++void
++Root::set_color_dead_bg(int64_t color) {
++ color_dead_bg = color;
++}
++
++// Active
++int
++Root::get_color_active_fg() {
++ return color_active_fg;
++}
++
++void
++Root::set_color_active_fg(int64_t color) {
++ color_active_fg = color;
++}
++
++int
++Root::get_color_active_bg() {
++ return color_active_bg;
++}
++
++void
++Root::set_color_active_bg(int64_t color) {
++ color_active_bg = color;
++}
++
++// Finished
++int
++Root::get_color_finished_fg() {
++ return color_finished_fg;
++}
++
++void
++Root::set_color_finished_fg(int64_t color) {
++ color_finished_fg = color;
++}
++
++int
++Root::get_color_finished_bg() {
++ return color_finished_bg;
++}
++
++void
++Root::set_color_finished_bg(int64_t color) {
++ color_finished_bg = color;
++}
++
+ }
+diff --git a/src/ui/root.h b/src/ui/root.h
+index cbc5ff4..a550aeb 100644
+--- a/src/ui/root.h
++++ b/src/ui/root.h
+@@ -83,6 +83,23 @@ public:
+ void set_down_throttle_i64(int64_t throttle) { set_down_throttle(throttle >> 10); }
+ void set_up_throttle_i64(int64_t throttle) { set_up_throttle(throttle >> 10); }
+
++ int get_color_inactive_fg();
++ void set_color_inactive_fg(int64_t color);
++ int get_color_inactive_bg();
++ void set_color_inactive_bg(int64_t color);
++ int get_color_dead_fg();
++ void set_color_dead_fg(int64_t color);
++ int get_color_dead_bg();
++ void set_color_dead_bg(int64_t color);
++ int get_color_active_fg();
++ void set_color_active_fg(int64_t color);
++ int get_color_active_bg();
++ void set_color_active_bg(int64_t color);
++ int get_color_finished_fg();
++ void set_color_finished_fg(int64_t color);
++ int get_color_finished_bg();
++ void set_color_finished_bg(int64_t color);
++
+ void adjust_down_throttle(int throttle);
+ void adjust_up_throttle(int throttle);
+
+@@ -105,6 +122,15 @@ private:
+ WStatusbar* m_windowStatusbar;
+
+ input::Bindings m_bindings;
++
++ int64_t color_inactive_fg;
++ int64_t color_inactive_bg;
++ int64_t color_dead_fg;
++ int64_t color_dead_bg;
++ int64_t color_active_fg;
++ int64_t color_active_bg;
++ int64_t color_finished_fg;
++ int64_t color_finished_bg;
+ };
+
+ }
diff --git a/rtorrent-0.9.6_vi_keybinding_tjwoosta.patch b/rtorrent-0.9.6_vi_keybinding_tjwoosta.patch
new file mode 100755
index 000000000000..a4c77fbdd7bd
--- /dev/null
+++ b/rtorrent-0.9.6_vi_keybinding_tjwoosta.patch
@@ -0,0 +1,172 @@
+diff -ruN a/src/ui/download_list.cc b/src/ui/download_list.cc
+--- a/src/ui/download_list.cc 2014-05-14 10:30:51.000000000 -0400
++++ b/src/ui/download_list.cc 2014-12-09 00:22:43.582812276 -0500
+@@ -349,11 +349,14 @@
+
+ m_uiArray[DISPLAY_LOG]->bindings()[KEY_LEFT] =
+ m_uiArray[DISPLAY_LOG]->bindings()['B' - '@'] =
+- m_uiArray[DISPLAY_LOG]->bindings()[' '] = std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_DOWNLOAD_LIST);
++ m_uiArray[DISPLAY_LOG]->bindings()[' '] =
++ m_uiArray[DISPLAY_LOG]->bindings()['h'] = std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_DOWNLOAD_LIST);
+
+ m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()[KEY_RIGHT] =
+- m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['F' - '@'] = std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_DOWNLOAD);
+- m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['l'] = std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_LOG);
++ m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['F' - '@'] =
++ m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['l'] = std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_DOWNLOAD);
++
++ m_uiArray[DISPLAY_DOWNLOAD_LIST]->bindings()['L'] = std::tr1::bind(&DownloadList::activate_display, this, DISPLAY_LOG);
+ }
+
+ }
+diff -ruN a/src/ui/element_chunks_seen.cc b/src/ui/element_chunks_seen.cc
+--- a/src/ui/element_chunks_seen.cc 2014-05-14 10:30:51.000000000 -0400
++++ b/src/ui/element_chunks_seen.cc 2014-12-09 00:22:43.582812276 -0500
+@@ -52,10 +52,14 @@
+ m_window(NULL),
+ m_focus(0) {
+
+- m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
++ m_bindings[KEY_LEFT] = m_bindings['B' - '@'] =
++ m_bindings['h'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
++
++ m_bindings[KEY_DOWN] = m_bindings['N' - '@'] =
++ m_bindings['j'] = std::tr1::bind(&ElementChunksSeen::receive_next, this);
++ m_bindings[KEY_UP] = m_bindings['P' - '@'] =
++ m_bindings['k'] = std::tr1::bind(&ElementChunksSeen::receive_prev, this);
+
+- m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementChunksSeen::receive_next, this);
+- m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementChunksSeen::receive_prev, this);
+ m_bindings[KEY_NPAGE] = std::tr1::bind(&ElementChunksSeen::receive_pagenext, this);
+ m_bindings[KEY_PPAGE] = std::tr1::bind(&ElementChunksSeen::receive_pageprev, this);
+ }
+diff -ruN a/src/ui/element_download_list.cc b/src/ui/element_download_list.cc
+--- a/src/ui/element_download_list.cc 2014-05-14 10:30:51.000000000 -0400
++++ b/src/ui/element_download_list.cc 2014-12-09 00:22:43.583812276 -0500
+@@ -97,8 +97,8 @@
+ m_bindings['9'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "leeching");
+ m_bindings['0'] = std::tr1::bind(&ElementDownloadList::receive_change_view, this, "active");
+
+- m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementDownloadList::receive_prev, this);
+- m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementDownloadList::receive_next, this);
++ m_bindings[KEY_UP] = m_bindings['k'] = m_bindings['P' - '@'] = std::tr1::bind(&ElementDownloadList::receive_prev, this);
++ m_bindings[KEY_DOWN] = m_bindings['j'] = m_bindings['N' - '@'] = std::tr1::bind(&ElementDownloadList::receive_next, this);
+ }
+
+ void
+diff -ruN a/src/ui/element_file_list.cc b/src/ui/element_file_list.cc
+--- a/src/ui/element_file_list.cc 2014-05-14 10:30:51.000000000 -0400
++++ b/src/ui/element_file_list.cc 2014-12-09 00:22:43.583812276 -0500
+@@ -63,8 +63,8 @@
+ m_selected(iterator(d->download()->file_list()->begin())),
+ m_collapsed(false) {
+
+- m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
+- m_bindings[KEY_RIGHT] = m_bindings['F' - '@'] = std::tr1::bind(&ElementFileList::receive_select, this);
++ m_bindings[KEY_LEFT] = m_bindings['h'] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
++ m_bindings[KEY_RIGHT] = m_bindings['l'] = m_bindings['F' - '@'] = std::tr1::bind(&ElementFileList::receive_select, this);
+
+ m_bindings[' '] = std::tr1::bind(&ElementFileList::receive_priority, this);
+ m_bindings['*'] = std::tr1::bind(&ElementFileList::receive_change_all, this);
+@@ -72,8 +72,8 @@
+ m_bindings[KEY_NPAGE] = std::tr1::bind(&ElementFileList::receive_pagenext, this);
+ m_bindings[KEY_PPAGE] = std::tr1::bind(&ElementFileList::receive_pageprev, this);
+
+- m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementFileList::receive_next, this);
+- m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementFileList::receive_prev, this);
++ m_bindings[KEY_DOWN] = m_bindings['j'] = m_bindings['N' - '@'] = std::tr1::bind(&ElementFileList::receive_next, this);
++ m_bindings[KEY_UP] = m_bindings['k'] = m_bindings['P' - '@'] = std::tr1::bind(&ElementFileList::receive_prev, this);
+ }
+
+ inline ElementText*
+diff -ruN a/src/ui/element_menu.cc b/src/ui/element_menu.cc
+--- a/src/ui/element_menu.cc 2014-05-14 10:30:51.000000000 -0400
++++ b/src/ui/element_menu.cc 2014-12-09 00:22:43.583812276 -0500
+@@ -72,11 +72,11 @@
+ m_entry(entry_invalid) {
+
+ // Move bindings into a function that defines default bindings.
+- m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
+- m_bindings[KEY_RIGHT] = m_bindings['F' - '@'] = std::tr1::bind(&ElementMenu::entry_select, this);
++ m_bindings[KEY_LEFT] = m_bindings['h'] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
++ m_bindings[KEY_RIGHT] = m_bindings['l'] = m_bindings['F' - '@'] = std::tr1::bind(&ElementMenu::entry_select, this);
+
+- m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementMenu::entry_prev, this);
+- m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementMenu::entry_next, this);
++ m_bindings[KEY_UP] = m_bindings['k'] = m_bindings['P' - '@'] = std::tr1::bind(&ElementMenu::entry_prev, this);
++ m_bindings[KEY_DOWN] = m_bindings['j'] = m_bindings['N' - '@'] = std::tr1::bind(&ElementMenu::entry_next, this);
+ }
+
+ ElementMenu::~ElementMenu() {
+diff -ruN a/src/ui/element_peer_list.cc b/src/ui/element_peer_list.cc
+--- a/src/ui/element_peer_list.cc 2014-05-14 10:30:51.000000000 -0400
++++ b/src/ui/element_peer_list.cc 2014-12-09 00:22:43.584812276 -0500
+@@ -76,14 +76,14 @@
+
+ m_elementInfo->slot_exit(std::tr1::bind(&ElementPeerList::activate_display, this, DISPLAY_LIST));
+
+- m_bindings['k'] = std::tr1::bind(&ElementPeerList::receive_disconnect_peer, this);
++ m_bindings['K'] = std::tr1::bind(&ElementPeerList::receive_disconnect_peer, this);
+ m_bindings['*'] = std::tr1::bind(&ElementPeerList::receive_snub_peer, this);
+ m_bindings['B'] = std::tr1::bind(&ElementPeerList::receive_ban_peer, this);
+- m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
+- m_bindings[KEY_RIGHT] = m_bindings['F' - '@'] = std::tr1::bind(&ElementPeerList::activate_display, this, DISPLAY_INFO);
++ m_bindings[KEY_LEFT] = m_bindings['h'] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
++ m_bindings[KEY_RIGHT] = m_bindings['l'] = m_bindings['F' - '@'] = std::tr1::bind(&ElementPeerList::activate_display, this, DISPLAY_INFO);
+
+- m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementPeerList::receive_prev, this);
+- m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementPeerList::receive_next, this);
++ m_bindings[KEY_UP] = m_bindings['k'] = m_bindings['P' - '@'] = std::tr1::bind(&ElementPeerList::receive_prev, this);
++ m_bindings[KEY_DOWN] = m_bindings['j'] = m_bindings['N' - '@'] = std::tr1::bind(&ElementPeerList::receive_next, this);
+ }
+
+ ElementPeerList::~ElementPeerList() {
+diff -ruN a/src/ui/element_text.cc b/src/ui/element_text.cc
+--- a/src/ui/element_text.cc 2014-05-14 10:30:51.000000000 -0400
++++ b/src/ui/element_text.cc 2014-12-09 00:22:43.584812276 -0500
+@@ -54,7 +54,7 @@
+ m_columnWidth(0) {
+
+ // Move bindings into a function that defines default bindings.
+- m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
++ m_bindings[KEY_LEFT] = m_bindings['h'] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
+
+ // m_bindings[KEY_UP] = std::tr1::bind(this, &ElementText::entry_prev);
+ // m_bindings[KEY_DOWN] = std::tr1::bind(this, &ElementText::entry_next);
+diff -ruN a/src/ui/element_tracker_list.cc b/src/ui/element_tracker_list.cc
+--- a/src/ui/element_tracker_list.cc 2014-05-14 10:30:51.000000000 -0400
++++ b/src/ui/element_tracker_list.cc 2014-12-09 00:22:43.584812276 -0500
+@@ -54,13 +54,13 @@
+ m_window(NULL),
+ m_focus(0) {
+
+- m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
++ m_bindings[KEY_LEFT] = m_bindings['h'] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
+
+ m_bindings[' '] = std::tr1::bind(&ElementTrackerList::receive_cycle_group, this);
+ m_bindings['*'] = std::tr1::bind(&ElementTrackerList::receive_disable, this);
+
+- m_bindings[KEY_DOWN] = m_bindings['N' - '@'] = std::tr1::bind(&ElementTrackerList::receive_next, this);
+- m_bindings[KEY_UP] = m_bindings['P' - '@'] = std::tr1::bind(&ElementTrackerList::receive_prev, this);
++ m_bindings[KEY_DOWN] = m_bindings['j'] = m_bindings['N' - '@'] = std::tr1::bind(&ElementTrackerList::receive_next, this);
++ m_bindings[KEY_UP] = m_bindings['k'] = m_bindings['P' - '@'] = std::tr1::bind(&ElementTrackerList::receive_prev, this);
+ }
+
+ void
+diff -ruN a/src/ui/element_transfer_list.cc b/src/ui/element_transfer_list.cc
+--- a/src/ui/element_transfer_list.cc 2014-05-14 10:30:51.000000000 -0400
++++ b/src/ui/element_transfer_list.cc 2014-12-09 00:22:43.585812276 -0500
+@@ -52,10 +52,10 @@
+ m_window(NULL),
+ m_focus(0) {
+
+- m_bindings[KEY_LEFT] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
++ m_bindings[KEY_LEFT] = m_bindings['h'] = m_bindings['B' - '@'] = std::tr1::bind(&slot_type::operator(), &m_slot_exit);
+
+- m_bindings[KEY_DOWN] = std::tr1::bind(&ElementTransferList::receive_next, this);
+- m_bindings[KEY_UP] = std::tr1::bind(&ElementTransferList::receive_prev, this);
++ m_bindings[KEY_DOWN] = m_bindings['j'] = std::tr1::bind(&ElementTransferList::receive_next, this);
++ m_bindings[KEY_UP] = m_bindings['k'] = std::tr1::bind(&ElementTransferList::receive_prev, this);
+ m_bindings[KEY_NPAGE] = std::tr1::bind(&ElementTransferList::receive_pagenext, this);
+ m_bindings[KEY_PPAGE] = std::tr1::bind(&ElementTransferList::receive_pageprev, this);
+ }