logoalt Hacker News

rat_on_the_runyesterday at 3:55 PM9 repliesview on HN

I wish the browsers had a function of disabling all keyboard shortcuts of a website. I binded Ctrl+E to opening a new tab just beside the current tab (built-in hotkey in Brave). It's frustrating to see it changed to something like opening the emoji menu on Discord.


Replies

declan_robertsyesterday at 4:15 PM

Ctrl+f is a bad offender. No I don't want to use your contextual search. I want to search for this word on this page!

show 5 replies
blfryesterday at 4:01 PM

Another one is hijcking ctrl+click (open in the new tab) into mere click (open here). I am shocked how many ecommerce sites do this.

show 3 replies
jeffalyanakyesterday at 9:35 PM

Rather than outright disabling it, I wish it was a permission the site would have to request.

That way trusted sites that used it responsibly could be given permission, but it could not be used by any random site.

show 1 reply
nesk_today at 4:22 AM

Actually, you can do that with Firefox, either per site or as a global policy.

https://superuser.com/a/1317514

igor47yesterday at 4:42 PM

I use vimium in Firefox and so my default key bindings are the plug-in ones. I push 't' to create a new tab, for instance. If I want to use the website key bindings I have to to into "insert mode" ('i'), or I opt into specific keys by site.

I do like when websites use ctrl-k -- it means nothing to my plug-in so websites always get it, plus it helps with key binding discovery.

kuleyesterday at 4:19 PM

Looking at you ctrl+r in web outlook...I want to reload the page not reply to the email!

show 1 reply
varenctoday at 12:13 AM

I keep a bookmarklet handy that blocks all keypress listeners to disable this stuff. Agreed it's quite annoying! Can share if desired, though pretty straightforward.

joquarkyyesterday at 5:58 PM

There should be a toggle control near the navigation buttons that toggles between document mode and app mode.

mrandishyesterday at 5:51 PM

I recently vibe-coded a browser UserScript to ensure certain keys are always passed through to my browser (and any other scripts I'm running). There's also an 'aggressive mode' activated by an assignable hotkey for poorly behaved sites that refuse to pass through any keys.

  // ==UserScript==
  // @name           Key Passthrough 2.0
  // @description    Ensure specific hotkeys reach userscripts on greedy sites. Ctrl+Shift+/ toggles aggressive mode for sites that swallow keys entirely.
  // @run-at         document-start
  // @include        *
  // @exclude        http://192.168.*
  // Always-enabled key codes: 27=Esc, 116=F5 (Refresh), 166=Browser_Back, 167=Browser_Fwd, 191=/
  // Other keycodes to consider: 8=BS, 9=Tab, 16/160/161=Shift, 17/162/163=Ctrl, 18=Alt, 37=LArrow, 39=RArrow, 46=Delete, 112=F1
  // ==/UserScript==

  (function () {
    'use strict';

    // Keys to passthrough in normal mode.
    // Esc, Ctrl, / (191) and Browser nav (166/167) are the core cases.
    // F1/F5 included if you have AHK remaps on those.
    // Esc included to prevent sites trapping it in overlays.
    const PASSTHROUGH_KEYS = new Set([27, 116, 166, 167, 191]);

    // Aggressive mode toggle hotkey: Ctrl+Shift+/
    const AGGRESSIVE_TOGGLE_CODE = 191;

    const REFIRE_FLAG = '_kp_refire';

    let aggressiveMode = sessionStorage.getItem('kp_aggressive') === '1';

    const logPrefix = '[KeyPassthrough]';

    const announce = (msg) => console.log(`${logPrefix} ${msg}`);

    if (aggressiveMode) announce('Aggressive mode ON (persisted from earlier in session)');

    // --- Normal mode ---
    // We're first in the capture chain at document-start.
    // For passthrough keys, do nothing — just let the event propagate naturally.
    // The site's listeners follow ours in the chain, so we've already won the race.

    // --- Aggressive mode ---
    // For sites that still swallow keys via stopImmediatePropagation in an
    // inline <script> that races document-start: block the site's listeners,
    // then re-dispatch a clone after the current call stack clears so our
    // userscripts get a clean second shot.

    function refire(e) {
        // Build a plain init object from the original event
        const init = {
            key:            e.key,
            code:           e.code,
            keyCode:        e.keyCode,
            which:          e.which,
            charCode:       e.charCode,
            ctrlKey:        e.ctrlKey,
            shiftKey:       e.shiftKey,
            altKey:         e.altKey,
            metaKey:        e.metaKey,
            repeat:         e.repeat,
            bubbles:        true,
            cancelable:     true,
            composed:       true,
        };
        const clone = new KeyboardEvent(e.type, init);
        clone[REFIRE_FLAG] = true;
        // After current capture/bubble cycle fully completes
        setTimeout(() => document.dispatchEvent(clone), 0);
    }

    function handleKey(e) {
        // Ignore our own re-dispatched events
        if (e[REFIRE_FLAG]) return;

        // Aggressive mode toggle: Ctrl+Shift+/
        if (e.ctrlKey && e.shiftKey && e.keyCode === AGGRESSIVE_TOGGLE_CODE) {
            aggressiveMode = !aggressiveMode;
            sessionStorage.setItem('kp_aggressive', aggressiveMode ? '1' : '0');
            announce(`Aggressive mode ${aggressiveMode ? 'ON' : 'OFF'}`);
            e.stopImmediatePropagation();
            return;
        }

        if (!PASSTHROUGH_KEYS.has(e.keyCode)) return;

        if (aggressiveMode) {
            // Block the site from seeing this key, then re-dispatch for our scripts
            e.stopImmediatePropagation();
            refire(e);
        }
        // Normal mode: do nothing, let event propagate naturally
    }
    document.addEventListener('keydown', handleKey, true);
    document.addEventListener('keyup',   handleKey, true);
  })();