From 2b7297cc7e67f031fb8db8f60685ac7b7557edcd Mon Sep 17 00:00:00 2001 From: DRC Date: Mon, 20 Jan 2025 18:00:25 -0500 Subject: [PATCH] Viewer: Add parameter to disable hotkeys This is a companion to the NoMacHotkeys parameter, to address rare cases in which users may want to pass all Ctrl-Alt-Shift key sequences to the VNC server. (All Ctrl-Alt-Shift hotkeys have an equivalent F8 menu hotkey, so one could use, for instance, {menu key} + F instead of Ctrl-Alt-Shift-F in order to toggle full-screen mode.) Also change "key combination" to "key sequence" in the NoMacHotkeys parameter documentation, for consistency. --- java/com/turbovnc/rfb/Params.java | 16 ++-- .../com/turbovnc/vncviewer/DesktopWindow.java | 3 +- java/com/turbovnc/vncviewer/F8Menu.java | 79 ++++++++++++------- 3 files changed, 63 insertions(+), 35 deletions(-) diff --git a/java/com/turbovnc/rfb/Params.java b/java/com/turbovnc/rfb/Params.java index ad0dcf69e..19bb5c617 100644 --- a/java/com/turbovnc/rfb/Params.java +++ b/java/com/turbovnc/rfb/Params.java @@ -646,6 +646,12 @@ public void save(String node) { new MenuKeyParameter("MenuKey", this, true, "The key used to display the popup menu", "F8"); + public BoolParameter noHotkeys = + new BoolParameter("NoHotkeys", this, false, + "Setting this parameter disables all Ctrl-Alt-Shift hotkeys, thus " + + "allowing those key sequences to be transmitted to the VNC server.", + false); + public BoolParameter noMacHotkeys = new BoolParameter("NoMacHotkeys", this, false, Utils.isMac() ? "On macOS, the TurboVNC Viewer normally assigns " + @@ -653,11 +659,11 @@ public void save(String node) { "However, since the Command key maps to the Super/Meta key on Un*x " + "systems, those Command hotkeys may interfere with hotkeys used by " + "certain applications (such as Emacs) on the remote system. Setting this " + - "parameter allows as many Command key combinations as possible to be " + - "transmitted to the VNC server as Super/Meta key combinations, although " + - "some Command key combinations (notably Command-F5, Command-Tab, " + - "Command-H, Command-Q, Command-Comma, and Command-Space) will still be " + - "intercepted by macOS." : null, false); + "parameter allows as many Command key sequences as possible to be " + + "transmitted to the VNC server as Super/Meta key sequences, although some " + + "Command key sequences (notably Command-F5, Command-Tab, Command-H, " + + "Command-Q, Command-Comma, and Command-Space) will still be intercepted " + + "by macOS." : null, false); // Prevent the viewer from sending Ctrl-Alt-Del and Ctrl-Esc to the server public BoolParameter restricted = diff --git a/java/com/turbovnc/vncviewer/DesktopWindow.java b/java/com/turbovnc/vncviewer/DesktopWindow.java index 10b197615..2a164e770 100644 --- a/java/com/turbovnc/vncviewer/DesktopWindow.java +++ b/java/com/turbovnc/vncviewer/DesktopWindow.java @@ -633,7 +633,8 @@ public void keyPressed(KeyEvent e) { int ctrlAltShiftMask = InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK; - if ((e.getModifiersEx() & ctrlAltShiftMask) == ctrlAltShiftMask && + if (!cc.params.noHotkeys.get() && + (e.getModifiersEx() & ctrlAltShiftMask) == ctrlAltShiftMask && (!Utils.isWindows() || !e.isAltGraphDown())) { switch (e.getKeyCode()) { case KeyEvent.VK_F: diff --git a/java/com/turbovnc/vncviewer/F8Menu.java b/java/com/turbovnc/vncviewer/F8Menu.java index 8f88c2a05..71e58b540 100644 --- a/java/com/turbovnc/vncviewer/F8Menu.java +++ b/java/com/turbovnc/vncviewer/F8Menu.java @@ -1,5 +1,5 @@ -/* Copyright (C) 2012-2015, 2017-2018, 2020-2022, 2024 D. R. Commander. - * All Rights Reserved. +/* Copyright (C) 2012-2015, 2017-2018, 2020-2022, 2024-2025 + * D. R. Commander. All Rights Reserved. * Copyright (C) 2011, 2013 Brian P. Hinz * Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * @@ -38,55 +38,75 @@ public F8Menu(CConn cc_) { exit = addMenuItem("Close Connection", KeyEvent.VK_C); addSeparator(); } - options = addMenuItem("Options... (Ctrl-Alt-Shift-O)", KeyEvent.VK_O); - info = addMenuItem("Connection Info... (Ctrl-Alt-Shift-I)", - KeyEvent.VK_I); + options = addMenuItem("Options..." + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-O)"), KeyEvent.VK_O); + info = addMenuItem("Connection Info..." + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-I)"), KeyEvent.VK_I); info.setDisplayedMnemonicIndex(11); - profile = new JCheckBoxMenuItem("Performance Info... (Ctrl-Alt-Shift-P)"); + profile = new JCheckBoxMenuItem("Performance Info..." + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-P)")); profile.setMnemonic(KeyEvent.VK_P); profile.setSelected(cc.profileDialog.isVisible()); profile.addActionListener(this); add(profile); addSeparator(); - refresh = addMenuItem("Request Screen Refresh (Ctrl-Alt-Shift-R)", - KeyEvent.VK_R); + refresh = addMenuItem("Request Screen Refresh" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-R)"), KeyEvent.VK_R); refresh.setDisplayedMnemonicIndex(15); - losslessRefresh = - addMenuItem("Request Lossless Refresh (Ctrl-Alt-Shift-L)", - KeyEvent.VK_L); + losslessRefresh = addMenuItem("Request Lossless Refresh" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-L)"), KeyEvent.VK_L); losslessRefresh.setDisplayedMnemonicIndex(8); - screenshot = - addMenuItem("Save Remote Desktop Image... (Ctrl-Alt-Shift-M)", - KeyEvent.VK_M); + screenshot = addMenuItem("Save Remote Desktop Image..." + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-M)"), KeyEvent.VK_M); screenshot.setDisplayedMnemonicIndex(21); addSeparator(); - fullScreen = new JCheckBoxMenuItem("Full Screen (Ctrl-Alt-Shift-F)"); + fullScreen = new JCheckBoxMenuItem("Full Screen" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-F)")); fullScreen.setMnemonic(KeyEvent.VK_F); fullScreen.setSelected(cc.params.fullScreen.get()); fullScreen.addActionListener(this); add(fullScreen); - defaultSize = - addMenuItem("Default Window Size/Position (Ctrl-Alt-Shift-Z)", - KeyEvent.VK_Z); - zoomIn = addMenuItem("Zoom In (Ctrl-Alt-Shift-9)", KeyEvent.VK_9); - zoomOut = addMenuItem("Zoom Out (Ctrl-Alt-Shift-8)", KeyEvent.VK_8); - zoom100 = addMenuItem("Zoom 100% (Ctrl-Alt-Shift-0)", KeyEvent.VK_0); - showToolbar = new JCheckBoxMenuItem("Show Toolbar (Ctrl-Alt-Shift-T)"); + defaultSize = addMenuItem("Default Window Size/Position" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-Z)"), KeyEvent.VK_Z); + zoomIn = addMenuItem("Zoom In" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-9)"), KeyEvent.VK_9); + zoomOut = addMenuItem("Zoom Out" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-8)"), KeyEvent.VK_8); + zoom100 = addMenuItem("Zoom 100%" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-0)"), KeyEvent.VK_0); + showToolbar = new JCheckBoxMenuItem("Show Toolbar" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-T)")); showToolbar.setMnemonic(KeyEvent.VK_T); showToolbar.setSelected(cc.params.toolbar.get()); showToolbar.addActionListener(this); add(showToolbar); - tileWindows = addMenuItem("Tile All Viewer Windows (Ctrl-Alt-Shift-X)", - KeyEvent.VK_X); + tileWindows = addMenuItem("Tile All Viewer Windows" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-X)"), KeyEvent.VK_X); addSeparator(); - viewOnly = new JCheckBoxMenuItem("View Only (Ctrl-Alt-Shift-V)"); + viewOnly = new JCheckBoxMenuItem("View Only" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-V)")); viewOnly.setMnemonic(KeyEvent.VK_V); viewOnly.setSelected(cc.params.viewOnly.get()); viewOnly.addActionListener(this); add(viewOnly); if (Utils.osGrab() && Helper.isAvailable()) { - grabKeyboard = - new JCheckBoxMenuItem("Grab Keyboard (Ctrl-Alt-Shift-G)"); + grabKeyboard = new JCheckBoxMenuItem("Grab Keyboard" + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-G)")); grabKeyboard.setMnemonic(KeyEvent.VK_G); grabKeyboard.setSelected(VncViewer.isKeyboardGrabbed()); grabKeyboard.addActionListener(this); @@ -103,8 +123,9 @@ public F8Menu(CConn cc_) { clipboard = addMenuItem("Clipboard..."); addSeparator(); if (!cc.params.noNewConn.get()) { - newConn = addMenuItem("New Connection... (Ctrl-Alt-Shift-N)", - KeyEvent.VK_N); + newConn = addMenuItem("New Connection..." + + (cc.params.noHotkeys.get() ? "" : + " (Ctrl-Alt-Shift-N)"), KeyEvent.VK_N); addSeparator(); } about = addMenuItem("About TurboVNC Viewer...", KeyEvent.VK_A);