Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

const path = require('path');
const fs = require('fs');
const { app, BrowserWindow } = require('electron');
const { app, BrowserWindow, Menu } = require('electron');
const { registerIpc } = require('./ipc');
const { parentToolDir, appDir } = require('./paths');
const { ensureFontsInstalled } = require('./fonts');
Expand Down Expand Up @@ -155,6 +155,12 @@ function openCscopeWindow(ctx) {

app.whenReady().then(() => {
startupMark('app.whenReady');
// Drop the default Electron application menu. With autoHideMenuBar the hidden
// menu still captures the Alt key and Alt+<mnemonic> combos (e.g. Alt+F for
// "File"), which swallowed the renderer's Alt+F "Select Folder" hotkey before
// it could fire. Removing the menu frees all Alt-based shortcuts for the app's
// own keydown handlers.
Menu.setApplicationMenu(null);
// Optional CLI arg: a folder to pre-fill in the first tab (e.g. from the
// Explorer right-click menu). Resolve it before wiring IPC so the renderer
// can pull it via 'app:getCliFolder' once it has finished booting. Pushing it
Expand Down
31 changes: 22 additions & 9 deletions src/renderer/js/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@ class Tab {
}

// Select a folder row (keyboard navigation only; folders are not "file" selections).
_selectFolder(folderRow) {
_selectFolderRow(folderRow) {
if (!folderRow || !folderRow.classList.contains('tree-folderrow')) return;
this.selPaths = new Set(); // Clear multi-selection.
this.selIdx = -1; // No file selected.
Expand Down Expand Up @@ -1406,7 +1406,7 @@ class Tab {
const target = selectableRows.find((r) => allRows.indexOf(r) > folderPosInAll);
if (target) {
if (target.classList.contains('tree-folderrow')) {
this._selectFolder(target);
this._selectFolderRow(target);
} else {
const idx = Number(target.dataset.idx);
if (!Number.isNaN(idx)) {
Expand All @@ -1419,7 +1419,7 @@ class Tab {
const target = [...selectableRows].reverse().find((r) => allRows.indexOf(r) < folderPosInAll);
if (target) {
if (target.classList.contains('tree-folderrow')) {
this._selectFolder(target);
this._selectFolderRow(target);
} else {
const idx = Number(target.dataset.idx);
if (!Number.isNaN(idx)) {
Expand All @@ -1441,7 +1441,7 @@ class Tab {

// Determine if next row is a file or (collapsed) folder and select accordingly.
if (nextRow.classList.contains('tree-folderrow')) {
this._selectFolder(nextRow);
this._selectFolderRow(nextRow);
} else {
const nextIdx = Number(nextRow.dataset.idx);
if (!Number.isNaN(nextIdx)) {
Expand Down Expand Up @@ -1503,7 +1503,7 @@ class Tab {
if (folderRow && !this.treeCollapsed.has(this.selFolderKey)) {
// Folder is expanded: collapse it and stay.
this._setFolderRowCollapsed(folderRow, true);
this._selectFolder(folderRow);
this._selectFolderRow(folderRow);
return;
}
// Already collapsed: try to go up to parent folder.
Expand All @@ -1515,7 +1515,7 @@ class Tab {
: null;
if (parentFolderRow) {
this._setFolderRowCollapsed(parentFolderRow, true);
this._selectFolder(parentFolderRow);
this._selectFolderRow(parentFolderRow);
}
}
return;
Expand Down Expand Up @@ -1555,7 +1555,7 @@ class Tab {
}

// Stay on the (topmost) collapsed folder instead of jumping to a file.
this._selectFolder(topmostFolder);
this._selectFolderRow(topmostFolder);
}

async copyAllFiles() {
Expand Down Expand Up @@ -2044,6 +2044,21 @@ window.addEventListener('keydown', (e) => {
}
return;
}
// Alt+F -> Select Folder. Handled before the typing-target guard below so it
// works even while a form field (keyword/folder input) has focus; Alt+F has
// no native text-editing meaning, so intercepting it is safe.
if (e.altKey && !e.ctrlKey && !e.metaKey && (e.key === 'f' || e.key === 'F')) {
e.preventDefault();
tab._selectFolder();
return;
}
// Esc -> Stop a running search. Handled before the typing-target guard so it
// works even while a form field (keyword/filter input) has focus. When no
// search is running it falls through to the field's own native Esc behaviour.
if (e.key === 'Escape') {
if (tab.running) { e.preventDefault(); tab.stop(); }
return;
}
const target = e.target;
const isTypingTarget = !!(target && (
target.tagName === 'INPUT'
Expand All @@ -2054,8 +2069,6 @@ window.addEventListener('keydown', (e) => {
if (e.ctrlKey && (e.key === 'f' || e.key === 'F')) { e.preventDefault(); tab.focusKeywords(); }
else if (e.ctrlKey && (e.key === 'd' || e.key === 'D')) { e.preventDefault(); tab.focusFilter(); }
else if ((e.ctrlKey || e.metaKey) && !e.altKey && e.key === 'ArrowRight') { e.preventDefault(); tab.focusPreviewFirstMatch(); }
else if (e.altKey && !e.ctrlKey && !e.metaKey && (e.key === 'f' || e.key === 'F')) { e.preventDefault(); tab._selectFolder(); }
else if (e.key === 'Escape') { if (tab.running) { e.preventDefault(); tab.stop(); } }
else if (e.ctrlKey && (e.key === 't' || e.key === 'T')) { e.preventDefault(); manager.add(false); }
else if (e.ctrlKey && (e.key === 'w' || e.key === 'W')) { e.preventDefault(); manager.closeCurrent(); }
else if (e.altKey && e.key === 'ArrowDown') { e.preventDefault(); tab.focusFiles(); }
Expand Down
Loading