Page back/forward: Alt+Left/Right, mouse side buttons, optional on-screen buttons

Alt+Left/Right now go back/forward within the page (the standard browser
keys) instead of switching sites; sites switch with Ctrl+Tab, Ctrl+[ ] and
the standard Ctrl+PageUp/PageDown. New enableHistoryButtons option (off by
default) shows half-transparent back/forward buttons at the top middle.
Settable from the terminal menu and the Web UI.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013wi3ZQveYdjfcrEsyazq32
This commit is contained in:
Claude
2026-11-06 16:47:53 +00:00
parent 7ed2d4744c
commit 1775220312
10 changed files with 161 additions and 5 deletions
+75
View File
@@ -115,6 +115,19 @@ ipcRenderer.on('keyboard-button-enabled',(event,enabled)=>{
}
});
// On-screen back/forward buttons (top middle, half transparent) - an
// option for screens with no keyboard or mouse side buttons.
let historyButtonsEnabled=false;
let historyBar=null;
let historyBarHideTimer=null;
ipcRenderer.on('history-buttons-enabled',(event,enabled)=>{
historyButtonsEnabled=enabled===true;
console.log('[HISTORY-BTN] Back/forward buttons enabled: '+historyButtonsEnabled);
if(historyBar&&!historyButtonsEnabled){
historyBar.style.display='none';
}
});
ipcRenderer.on('nav-button-enabled',(event,enabled)=>{
navButtonEnabled=enabled;
console.log('[NAV-BTN] Navigation button enabled: '+enabled);
@@ -253,6 +266,56 @@ window.addEventListener('DOMContentLoaded',()=>{
document.body.appendChild(navButton);
}
// Back/forward buttons, top middle. The corners are often all taken by the
// menu, pause, keyboard and power buttons, so these sit between them.
const HISTORY_BAR_HIDE_DELAY=5000;
function createHistoryBar(){
if(historyBar)return;
historyBar=document.createElement('div');
historyBar.id='electron-history-bar';
historyBar.style.cssText=`
position:fixed;top:12px;left:50%;transform:translateX(-50%);
display:none;gap:14px;z-index:999999;opacity:0.5;
transition:opacity 0.15s;user-select:none;
`;
const makeButton=(label,direction,path)=>{
const b=document.createElement('div');
b.title=label;
b.innerHTML='<svg width="30" height="30" viewBox="0 0 24 24" fill="white"><path d="'+path+'"/></svg>';
b.style.cssText=`
width:56px;height:56px;background:rgba(44,62,80,0.9);
border:2px solid rgba(255,255,255,0.9);border-radius:50%;
display:flex;align-items:center;justify-content:center;cursor:pointer;
`;
b.addEventListener('click',(e)=>{
e.preventDefault();
e.stopPropagation();
ipcRenderer.send('history-nav',direction);
showHistoryBar();
});
return b;
};
historyBar.append(
makeButton('Back','back','M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z'),
makeButton('Forward','forward','M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z')
);
historyBar.addEventListener('mouseenter',()=>{historyBar.style.opacity='0.9';});
historyBar.addEventListener('mouseleave',()=>{historyBar.style.opacity='0.5';});
document.body.appendChild(historyBar);
}
function showHistoryBar(){
if(!historyButtonsEnabled)return;
if(!historyBar)createHistoryBar();
if(!historyBar)return;
historyBar.style.display='flex';
if(historyBarHideTimer)clearTimeout(historyBarHideTimer);
historyBarHideTimer=setTimeout(()=>{
if(historyBar)historyBar.style.display='none';
historyBarHideTimer=null;
},HISTORY_BAR_HIDE_DELAY);
}
// Power button in top-right corner (follows same show/hide logic as nav button)
let powerButton=null;
let powerButtonHideTimer=null;
@@ -918,11 +981,23 @@ window.addEventListener('DOMContentLoaded',()=>{
if(navButtonEnabled){
showNavButton();
}
showHistoryBar();
// Always show power button on user interaction
showPowerButton();
}
// Back/forward buttons also appear on plain mouse movement, for screens
// with a mouse but no touch (the other buttons wait for a click/keypress).
let lastHistoryMove=0;
document.addEventListener('mousemove',()=>{
if(!historyButtonsEnabled)return;
const now=Date.now();
if(now-lastHistoryMove<300)return;
lastHistoryMove=now;
showHistoryBar();
},{passive:true,capture:true});
// Show pause button on any user interaction
const pauseButtonTriggers=['mousedown','touchstart','keydown'];
pauseButtonTriggers.forEach(eventType=>{