diff --git a/web/index.html b/web/index.html
index d99f35164..55626330b 100755
--- a/web/index.html
+++ b/web/index.html
@@ -330,6 +330,14 @@
DEL |
Delete selected torrents |
+
+ i |
+ Toggle inspector |
+
+
+ l |
+ Move torrent/Set location |
+
m |
Move torrent/Set location |
diff --git a/web/javascript/transmission.js b/web/javascript/transmission.js
index 9cc2436ba..af3ca6752 100644
--- a/web/javascript/transmission.js
+++ b/web/javascript/transmission.js
@@ -455,11 +455,17 @@ Transmission.prototype = {
keyDown: function (ev) {
var handled = false;
var rows = this._rows;
+ var isInputFocused = $(ev.target).is('input');
+ var isDialogVisible = ($('.dialog_heading:visible').length > 0 || $('.ui-dialog:visible').length > 0);
+
+ // hotkeys
var up_key = ev.keyCode === 38; // up key pressed
var dn_key = ev.keyCode === 40; // down key pressed
var a_key = ev.keyCode === 65; // a key pressed
var c_key = ev.keyCode === 67; // c key pressed
var d_key = ev.keyCode === 68; // d key pressed
+ var i_key = ev.keyCode === 73; // i key pressed
+ var l_key = ev.keyCode === 76; // l key pressed
var m_key = ev.keyCode === 77; // m key pressed
var o_key = ev.keyCode === 79; // o key pressed
var p_key = ev.keyCode === 80; // p key pressed
@@ -474,62 +480,6 @@ Transmission.prototype = {
var esc_key = ev.keyCode === 27; // esc key pressed
var comma_key = ev.keyCode === 188; // comma key pressed
- if ($('.dialog_heading:visible').length == 0) {
- if (comma_key) {
- this.togglePrefsDialogClicked();
- handled = true;
- }
-
- if (a_key) {
- if (ev.shiftKey) {
- this.deselectAll();
- } else {
- this.selectAll();
- }
- handled = true;
- }
-
- if (c_key) {
- this.toggleCompactClicked();
- handled = true;
- }
-
- if ((backspace_key || del_key || d_key) && rows.length) {
- this.removeSelectedTorrents();
- handled = true;
- }
-
- if (m_key) {
- this.moveSelectedTorrents()
- handled = true;
- }
-
- if (o_key || u_key) {
- this.openTorrentClicked(ev);
- handled = true;
- }
-
- if (p_key) {
- this.stopSelectedTorrents();
- handled = true;
- }
-
- if (r_key) {
- this.startSelectedTorrents();
- handled = true;
- }
-
- if (t_key) {
- this.toggleTurtleClicked();
- handled = true;
- }
- }
-
- if (slash_key) {
- this.showHotkeysDialog();
- handled = true;
- }
-
if (enter_key) {
// handle other dialogs
if (dialog && dialog.isVisible()) {
@@ -582,42 +532,107 @@ Transmission.prototype = {
}
}
- if ((up_key || dn_key) && rows.length) {
- var last = this.indexOfLastTorrent(),
- i = last,
- anchor = this._shift_index,
- r,
- min = 0,
- max = rows.length - 1;
-
- if (dn_key && (i + 1 <= max)) {
- ++i;
- } else if (up_key && (i - 1 >= min)) {
- --i;
- };
-
- var r = rows[i];
-
- if (anchor >= 0) {
- // user is extending the selection
- // with the shift + arrow keys...
- if (((anchor <= last) && (last < i)) || ((anchor >= last) && (last > i))) {
- this.selectRow(r);
- } else if (((anchor >= last) && (i > last)) || ((anchor <= last) && (last > i))) {
- this.deselectRow(rows[last]);
- }
- } else {
- if (ev.shiftKey) {
- this.selectRange(r);
- } else {
- this.setSelectedRow(r);
- };
+ // Some hotkeys can only be used if the following conditions are met:
+ // 1. when no input fields are focused
+ // 2. when no other dialogs are visible
+ // 3. when the meta or ctrl key isn't pressed (i.e. opening dev tools shouldn't trigger the info panel)
+ if (!isInputFocused && !isDialogVisible && !ev.metaKey && !ev.ctrlKey) {
+ if (comma_key) {
+ this.togglePrefsDialogClicked();
+ handled = true;
+ }
+
+ if (slash_key) {
+ this.showHotkeysDialog();
+ handled = true;
+ }
+
+ if (a_key) {
+ if (ev.shiftKey) {
+ this.deselectAll();
+ } else {
+ this.selectAll();
+ }
+ handled = true;
+ }
+
+ if (c_key) {
+ this.toggleCompactClicked();
+ handled = true;
+ }
+
+ if ((backspace_key || del_key || d_key) && rows.length) {
+ this.removeSelectedTorrents();
+ handled = true;
+ }
+
+ if (i_key) {
+ this.toggleInspector();
+ handled = true;
+ }
+
+ if (m_key || l_key) {
+ this.moveSelectedTorrents()
+ handled = true;
+ }
+
+ if (o_key || u_key) {
+ this.openTorrentClicked(ev);
+ handled = true;
+ }
+
+ if (p_key) {
+ this.stopSelectedTorrents();
+ handled = true;
+ }
+
+ if (r_key) {
+ this.startSelectedTorrents();
+ handled = true;
+ }
+
+ if (t_key) {
+ this.toggleTurtleClicked();
+ handled = true;
+ }
+
+ if ((up_key || dn_key) && rows.length) {
+ var last = this.indexOfLastTorrent(),
+ i = last,
+ anchor = this._shift_index,
+ r,
+ min = 0,
+ max = rows.length - 1;
+
+ if (dn_key && (i + 1 <= max)) {
+ ++i;
+ } else if (up_key && (i - 1 >= min)) {
+ --i;
+ };
+
+ var r = rows[i];
+
+ if (anchor >= 0) {
+ // user is extending the selection
+ // with the shift + arrow keys...
+ if (((anchor <= last) && (last < i)) || ((anchor >= last) && (last > i))) {
+ this.selectRow(r);
+ } else if (((anchor >= last) && (i > last)) || ((anchor <= last) && (last > i))) {
+ this.deselectRow(rows[last]);
+ }
+ } else {
+ if (ev.shiftKey) {
+ this.selectRange(r);
+ } else {
+ this.setSelectedRow(r);
+ };
+ }
+ this._last_torrent_clicked = r.getTorrentId();
+ this.scrollToRow(r);
+ handled = true;
+ } else if (shift_key) {
+ this._shift_index = this.indexOfLastTorrent();
}
- this._last_torrent_clicked = r.getTorrentId();
- this.scrollToRow(r);
- handled = true;
- } else if (shift_key) {
- this._shift_index = this.indexOfLastTorrent();
}
return !handled;
@@ -841,74 +856,74 @@ Transmission.prototype = {
remote.savePrefs(o);
} else {
switch (id) {
- case 'statistics':
- this.showStatsDialog();
- break;
+ case 'statistics':
+ this.showStatsDialog();
+ break;
- case 'hotkeys':
- this.showHotkeysDialog();
- break;
+ case 'hotkeys':
+ this.showHotkeysDialog();
+ break;
- case 'about-button':
- o = 'Transmission ' + this.serverVersion;
- $('#about-dialog #about-title').html(o);
- $('#about-dialog').dialog({
- title: 'About',
- show: 'fade',
- hide: 'fade'
- });
- break;
+ case 'about-button':
+ o = 'Transmission ' + this.serverVersion;
+ $('#about-dialog #about-title').html(o);
+ $('#about-dialog').dialog({
+ title: 'About',
+ show: 'fade',
+ hide: 'fade'
+ });
+ break;
- case 'homepage':
- window.open('https://transmissionbt.com/');
- break;
+ case 'homepage':
+ window.open('https://transmissionbt.com/');
+ break;
- case 'tipjar':
- window.open('https://transmissionbt.com/donate/');
- break;
+ case 'tipjar':
+ window.open('https://transmissionbt.com/donate/');
+ break;
- case 'unlimited_download_rate':
- o = {};
- o[RPC._DownSpeedLimited] = false;
- remote.savePrefs(o);
- break;
+ case 'unlimited_download_rate':
+ o = {};
+ o[RPC._DownSpeedLimited] = false;
+ remote.savePrefs(o);
+ break;
- case 'limited_download_rate':
- o = {};
- o[RPC._DownSpeedLimited] = true;
- remote.savePrefs(o);
- break;
+ case 'limited_download_rate':
+ o = {};
+ o[RPC._DownSpeedLimited] = true;
+ remote.savePrefs(o);
+ break;
- case 'unlimited_upload_rate':
- o = {};
- o[RPC._UpSpeedLimited] = false;
- remote.savePrefs(o);
- break;
+ case 'unlimited_upload_rate':
+ o = {};
+ o[RPC._UpSpeedLimited] = false;
+ remote.savePrefs(o);
+ break;
- case 'limited_upload_rate':
- o = {};
- o[RPC._UpSpeedLimited] = true;
- remote.savePrefs(o);
- break;
+ case 'limited_upload_rate':
+ o = {};
+ o[RPC._UpSpeedLimited] = true;
+ remote.savePrefs(o);
+ break;
- case 'reverse_sort_order':
- if (element.menuItemIsSelected()) {
- dir = Prefs._SortAscending;
- element.deselectMenuItem();
- } else {
- dir = Prefs._SortDescending;
- element.selectMenuItem();
- }
- this.setSortDirection(dir);
- break;
+ case 'reverse_sort_order':
+ if (element.menuItemIsSelected()) {
+ dir = Prefs._SortAscending;
+ element.deselectMenuItem();
+ } else {
+ dir = Prefs._SortDescending;
+ element.selectMenuItem();
+ }
+ this.setSortDirection(dir);
+ break;
- case 'toggle_notifications':
- Notifications && Notifications.toggle();
- break;
+ case 'toggle_notifications':
+ Notifications && Notifications.toggle();
+ break;
- default:
- console.log('unhandled: ' + id);
- break;
+ default:
+ console.log('unhandled: ' + id);
+ break;
};
};
},