diff --git a/background_scripts/all_commands.js b/background_scripts/all_commands.js index 5abab2a16..d01c3c80a 100644 --- a/background_scripts/all_commands.js +++ b/background_scripts/all_commands.js @@ -519,6 +519,38 @@ const allCommands = [ background: true, }, + { + name: "mergeTabToExistingWindowOnLeft", + desc: "Move tab to an existing window on left, if exists", + group: "tabs", + advanced: true, + background: true, + }, + + { + name: "mergeTabToExistingWindowOnRight", + desc: "Move tab to an existing window on right, if exists", + group: "tabs", + advanced: true, + background: true, + }, + + { + name: "mergeTabToExistingWindowAbove", + desc: "Move tab to an existing window above, if exists", + group: "tabs", + advanced: true, + background: true, + }, + + { + name: "mergeTabToExistingWindowBelow", + desc: "Move tab to an existing window below, if exists", + group: "tabs", + advanced: true, + background: true, + }, + { name: "closeTabsOnLeft", desc: "Close tabs on the left", diff --git a/background_scripts/commands.js b/background_scripts/commands.js index 11673f22a..1878a372e 100644 --- a/background_scripts/commands.js +++ b/background_scripts/commands.js @@ -469,6 +469,10 @@ const defaultKeyMappings = { "g0": "firstTab", "g$": "lastTab", "W": "moveTabToNewWindow", + "wh": "mergeTabToExistingWindowOnLeft", + "wl": "mergeTabToExistingWindowOnRight", + "wk": "mergeTabToExistingWindowAbove", + "wj": "mergeTabToExistingWindowBelow", "t": "createTab", "yt": "duplicateTab", "x": "removeTab", diff --git a/background_scripts/main.js b/background_scripts/main.js index 06182dbc5..8f3fe36b2 100644 --- a/background_scripts/main.js +++ b/background_scripts/main.js @@ -235,6 +235,35 @@ function nextZoomLevel(currentZoom, steps) { } } +const moveTabToExistingWindow = function(orientation, currentTab) { + chrome.windows.getCurrent({}, currentWindow => { + chrome.windows.getAll({populate: true}, windows => { + const filteredWindows = windows.filter(window => { + if (window.id !== currentWindow.id) { + if (orientation === 'left') { + return window.left < currentWindow.left; + } else if (orientation === 'right') { + return window.left > currentWindow.left; + } else if (orientation === 'top') { + return window.top < currentWindow.top; + } else if (orientation === 'bottom') { + return window.top > currentWindow.top; + } + } + }); + if (filteredWindows.length > 0) { + const destinationWindow = filteredWindows[0]; + chrome.tabs.move(currentTab.id, { windowId: destinationWindow.id, index: -1 }).then(() => { + chrome.windows.get(destinationWindow.id, {populate: true}, newWindow => { + const newTab = newWindow.tabs.slice(-1)[0]; + selectSpecificTab({ id: newTab.id }); + }); + }); + } + }); + }); +}; + // These are commands which are bound to keystrokes which must be handled by the background page. // They are mapped in commands.js. const BackgroundCommands = { @@ -309,6 +338,19 @@ const BackgroundCommands = { }); }, + mergeTabToExistingWindowOnLeft(request) { + moveTabToExistingWindow("left", request.tab); + }, + mergeTabToExistingWindowOnRight(request) { + moveTabToExistingWindow("right", request.tab); + }, + mergeTabToExistingWindowAbove(request) { + moveTabToExistingWindow("top", request.tab); + }, + mergeTabToExistingWindowBelow(request) { + moveTabToExistingWindow("bottom", request.tab); + }, + nextTab(request) { return selectTab("next", request); },