Skip to content

Commit d2f948a

Browse files
feat: add merge all windows
1 parent 8d5e7dc commit d2f948a

File tree

3 files changed

+105
-6
lines changed

3 files changed

+105
-6
lines changed

manifest.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@
5656
"commands": {
5757
"merge-windows": {
5858
"suggested_key": {
59-
"default": "Alt+Shift+M",
60-
"linux": "Alt+Shift+M",
61-
"mac": "Ctrl+Shift+M",
62-
"windows": "Alt+Shift+M"
59+
"default": "Alt+Shift+W",
60+
"linux": "Alt+Shift+W",
61+
"mac": "Command+Shift+W",
62+
"windows": "Alt+Shift+W"
6363
},
6464
"description": "Merge windows"
6565
}

src/background.ts

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,18 @@ chrome.contextMenus.create({
210210
contexts: ['all'],
211211
});
212212

213-
chrome.contextMenus.onClicked.addListener(async function (info, tab) {
214-
if (!tab?.id) return;
213+
chrome.contextMenus.create({
214+
id: 'merge-windows',
215+
title: 'Merge All Windows',
216+
contexts: ['all'],
217+
});
215218

219+
chrome.contextMenus.onClicked.addListener(async function (info, tab) {
216220
if (info.menuItemId === 'rename-tab') {
221+
if (!tab?.id) return;
217222
await chrome.tabs.sendMessage(tab.id, { action: 'openPrompt' });
223+
} else if (info.menuItemId === 'merge-windows') {
224+
await mergeAllWindows();
218225
}
219226
});
220227

@@ -341,4 +348,75 @@ async function updateTabGroup(groupId: number, tmGroup: Group) {
341348
execute();
342349
}
343350

351+
// Merge Windows Command Handler
352+
chrome.commands.onCommand.addListener(async (command) => {
353+
if (command === 'merge-windows') {
354+
await mergeAllWindows();
355+
}
356+
});
357+
358+
/**
359+
* Merge all browser windows into the current window
360+
*/
361+
async function mergeAllWindows() {
362+
try {
363+
// Get all windows
364+
const windows = await chrome.windows.getAll({ populate: true });
365+
366+
if (windows.length <= 1) {
367+
console.log('[Tabee] Only one window open, nothing to merge');
368+
return;
369+
}
370+
371+
// Find the currently focused window or use the first normal window
372+
let targetWindow = windows.find((w) => w.focused);
373+
if (!targetWindow) {
374+
targetWindow = windows.find((w) => w.type === 'normal');
375+
}
376+
377+
if (!targetWindow || !targetWindow.id) {
378+
console.error('[Tabee] Could not find target window for merging');
379+
return;
380+
}
381+
382+
console.log(`[Tabee] Merging ${windows.length - 1} windows into window ${targetWindow.id}`);
383+
384+
// Move all tabs from other windows to the target window
385+
for (const window of windows) {
386+
// Skip the target window itself
387+
if (window.id === targetWindow.id) continue;
388+
389+
// Skip non-normal windows (popup, devtools, etc.)
390+
if (window.type !== 'normal') continue;
391+
392+
if (window.tabs && window.tabs.length > 0) {
393+
const tabIds = window.tabs
394+
.map((tab) => tab.id)
395+
.filter((id): id is number => id !== undefined);
396+
397+
if (tabIds.length > 0) {
398+
try {
399+
// Move tabs to target window
400+
await chrome.tabs.move(tabIds, {
401+
windowId: targetWindow.id,
402+
index: -1, // Append at the end
403+
});
404+
405+
console.log(`[Tabee] Moved ${tabIds.length} tabs from window ${window.id}`);
406+
} catch (error) {
407+
console.error(`[Tabee] Error moving tabs from window ${window.id}:`, error);
408+
}
409+
}
410+
}
411+
}
412+
413+
// Focus the target window
414+
await chrome.windows.update(targetWindow.id, { focused: true });
415+
416+
console.log('[Tabee] Windows merged successfully');
417+
} catch (error) {
418+
console.error('[Tabee] Error merging windows:', error);
419+
}
420+
}
421+
344422
export {};

src/components/options/center/sections/HelpPane.vue

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,32 @@
2424
<li>You can protect some websites from accidental closure with a confirm box.</li>
2525
<li>You can avoid duplicate tabs by setting up the unique property.</li>
2626
<li>You can mute the sound of any website before it plays it.</li>
27+
<li>You can merge all browser windows into one with a keyboard shortcut or context menu.</li>
2728
<li>And the icing on the cake... Combine all of them!</li>
2829
</ul>
2930
</div>
3031
</div>
3132

33+
<div class="card bg-base-200 mt-4">
34+
<div class="card-body">
35+
<h2 class="card-title">Keyboard Shortcuts</h2>
36+
37+
<h3 class="font-bold">Merge All Windows</h3>
38+
<p>
39+
Quickly merge all browser windows into the currently focused window using the keyboard
40+
shortcut:
41+
</p>
42+
<ul class="list-disc ml-3">
43+
<li><strong>Windows/Linux:</strong> <kbd class="kbd kbd-sm">Alt</kbd> + <kbd class="kbd kbd-sm">Shift</kbd> + <kbd class="kbd kbd-sm">W</kbd></li>
44+
<li><strong>Mac:</strong> <kbd class="kbd kbd-sm">⌘ Command</kbd> + <kbd class="kbd kbd-sm">Shift</kbd> + <kbd class="kbd kbd-sm">W</kbd></li>
45+
</ul>
46+
<p class="mt-2">
47+
You can also access this feature by right-clicking anywhere and selecting "Merge All
48+
Windows" from the context menu.
49+
</p>
50+
</div>
51+
</div>
52+
3253
<div class="card bg-base-200 mt-4">
3354
<div class="card-body">
3455
<h2 class="card-title">Tab Rules</h2>

0 commit comments

Comments
 (0)