Linux Java Swing 应用程序的 Kiosk 模式

2022-01-25 00:00:00 c linux kiosk java java-native-interface

如何在 [Ubuntu] Linux 机器上禁用操作系统级别的键盘快捷键(例如 Alt-Tab、Ctrl-Alt-Left/Right 等)?我正在开发一个全屏 Java Swing 应用程序,并且不希望用户能够任意切换任务离开程序.切换始终在顶部"标志是不够的;不得允许用户切换工作区、迁移焦点或任何其他此类事情.机器必须在应用程序执行前后正常运行.Google 表示这将需要 JNI 或 JNA,但我正在寻找更多的支持.

How can I disable OS-level keyboard shortcuts (e.g. Alt-Tab, Ctrl-Alt-Left/Right, etc.) on a [Ubuntu] Linux machine? I'm developing a full-screen Java Swing app and don't want the user to be able to task switch away from the program arbitrarily. It's not enough to toggle the "always on top" flag; users mustn't be allowed to switch workspaces, migrate focus or any other such things. The machine must function normally before and after the application is executed. Google says that this will require JNI or JNA but I'm looking for a bit more hand-holding.

推荐答案

在你的应用程序中尝试这样做是没有意义的,因为任何这些更改都需要由 X11 和/或窗口管理器处理,因为那些是响应命令的内容.假设您可以控制平台,请选择支持信息亭模式的窗口管理器.然后使用窗口管理器的设置启动您的应用程序并进入信息亭模式.

There's no point in trying to do this in your application because any of these changes are going to need to be handled by X11 and/or the window manager since those are what respond to the commands. Assuming that you have control of the platform, choose a window manager which supports a kiosk mode. Then use the window manager's settings to start your application and enter kiosk mode.

可以执行此操作的窗口管理器选项包括 KDE 或 twm-kiosk.

Options for window managers which can do this include KDE or twm-kiosk.

(如果您无法控制平台,那么您的应用程序无论如何都不太可能拦截诸如 ctrl-alt-backspace 之类的内容.)

(And if you don't have control of the platform, you're not likely to be able to have your application intercept things like ctrl-alt-backspace anyway.)

在回答问题的缩小版本时,他愿意让诸如 ctl-alt-backspace 之类的东西消失,只想要大多数键,包括 alt-tab 或其他类似的应用程序切换键组合,以下应该工作:

In response to a scaled-down version of the question in which he's willing to let things like ctl-alt-backspace go and just wants most of the keys including alt-tab or other similar application switching key combinations, the following should work:

您应该可以使用 XLib 的 XGrabKeyboard 方法来做到这一点通过 JNI.这个 Java/XLib JNI 按键捕获教程 应该是一个很好的起点.但是,它使用 XGrabKey,它只是被动地侦听密钥,并不会阻止其他应用程序接收它们.您将改为使用 XGrabKeyboard 主动捕获所有正常键盘事件(如果 this StackOverflow 问题是正确的,包括任务切换键).

You should be able to do this using XLib's XGrabKeyboard method through JNI. This Java/XLib JNI keypress capture tutorial should be a good starting point. However, it uses XGrabKey which just passively listens for keys and does not prevent other applications from receiving them. You'll instead want to use XGrabKeyboard which actively snags all of the normal keyboard events (which, if the premise of this StackOverflow question is correct, includes the task switching keys).

请注意,作为副作用,Swing 中的键捕获也可能会停止工作,因为您的 Swing 窗口将与您在 C 中创建的窗口分开.因此,您可能必须使用您的 JNI 接口来在需要时获取程序的按键.(尽管我肯定会建议在编写代码之前先对其进行测试.)如果您可以使用 Java AWT Native Interface 获取窗口 ID.(请注意,Swing 构建在 AWT 之上,因此这适用于 Swing.)但是,我不确定如何执行此操作.看起来您可以通过从显示器获取根窗口并从那里找到您的窗口来导航窗口树,但这有点奇怪.如果 AWT NI 只是告诉您窗口 ID,那就太好了,但它看起来不像这样做.

Note that as a side-effect, key capture in Swing will also probably stop working because your Swing windows are going to be separate from the window you create in C. As such, you will probably have to use your JNI interface to get key presses to your program when needed. (Although I would definitely advise testing it first before writing the code.) You might be able to avoid this if you can get the window using Java AWT Native Interface to get the window ID. (Note that Swing is built on top of AWT, so this will work for Swing.) However, I'm not sure how to do this. It looks like you might be able to navigate the window tree by getting the root window from the Display and going from there to find your Window, but it's all kind of weird. It would be nice if the AWT NI just told you the window ID, but it doesn't look like it does that.

作为这个警告提醒:XGrabKeyboard 不是安全接口 注意,这不会让其他程序无法看到键,但似乎窗口管理器不会使用 XQueryKeyMap,因此它可能会阻止任务切换.

As this warning Reminder: XGrabKeyboard is not a security interface notes, this doesn't make it impossible for other programs to see the keys, but it seems likely that window managers will not be using XQueryKeyMap so it is likely to prevent task switching.

相关文章