简体   繁体   English

如何配置JavaFX窗口使其浮动在Mac OSX Dock /菜单栏上方?

[英]How to do I configure a JavaFX Window to float above the Mac OSX Dock/Menubar?

I am attempting to create a transparent borderless JavaFX window/overlay on Mac OSX to allow users to select an area of the screen via drawing a rectangle and then screenshotting that area. 我试图在Mac OSX上创建一个透明的无边界JavaFX窗口/叠加层,以允许用户通过绘制一个矩形然后对该区域进行屏幕截图来选择屏幕的一个区域。

In order to do this on OSX, I must somehow configure my JavaFX window to float above the Mac OSX Dock/Menubar, as the window is automatically forced underneath both by default. 为了在OSX上执行此操作,我必须以某种方式将JavaFX窗口配置为浮动在Mac OSX Dock / Menubar上方,因为默认情况下该窗口会自动强行置于这两个窗口之下。 By this, I mean I cannot drag a window over the dock or menu bar as it is forced underneath it, making a proper overlay very difficult to achieve. 这样,我的意思是我无法将窗口拖到停靠栏或菜单栏上,因为它被迫压在其下方,这使得很难实现适当的覆盖。

How can I configure a JavaFX window's level similar to that of the NSWindow level via Cocoa? 如何通过Cocoa配置类似于NSWindow级别的JavaFX窗口级别?

The screenshots below (taken from a similar Electron-related post) highlight the issue and what I aim to achieve: 下面的屏幕截图(取自与电子相关的类似帖子)重点介绍了该问题以及我的目标:

Current Result: https://i.stack.imgur.com/nmGvG.png 当前结果: https : //i.stack.imgur.com/nmGvG.png

Intented Result: https://i.stack.imgur.com/kD6MR.png 预期结果: https ://i.stack.imgur.com/kD6MR.png

Thanks to jewelsea 's advice, I decided to look into using com.sun.glass.ui.Window to set a basic JavaFX Window's level to the maximum that Mac OSX can allow. 多亏了jewelsea的建议,我决定研究使用com.sun.glass.ui.Window将JavaFX Window的基本级别设置为Mac OSX可以允许的最大级别。 The code snippet below shows how easy it is to use com.sun.glass.ui.Window to override the window level of a given window handle/object which can be found using com.glass.ui.Window.getWindows() . 下面的代码片段显示了使用com.sun.glass.ui.Window覆盖给定窗口句柄/对象的窗口级别是多么容易,可以使用com.glass.ui.Window.getWindows()找到该窗口句柄/对象。 I found out how to use glass.ui.Window thanks to this answer found in another StackOverflow page. 由于在另一个StackOverflow页面中找到了此答案因此我找到了如何使用glass.ui.Window的方法。

However, there is one slight drawback (but is not an issue for me personally): decorated windows cannot be placed above the menubar even after setting the maximum window level, however, they can still be placed above the dock. 但是,有一个轻微的缺点(对我个人而言不是一个问题):即使在设置最大窗口级别之后,装饰后的窗口也不能放置在菜单栏上方,但是,它们仍可以放置在扩展坞上方。 If you wish to set a window above the menubar, you must first set it to Undecorated, show it, grab the window using com.sun.glass.ui.getWindows().get(window_index) and then set the window level to 3 (Max). 如果要在菜单栏上方设置一个窗口,则必须首先将其设置为“未装饰”,显示它,使用com.sun.glass.ui.getWindows()。get(window_index)抓取该窗口,然后将窗口级别设置为3 (最大值)。 You can set the X and Y coordinates for your window before or even after this, it seems to work both ways. 您可以在此之前或之后设置窗口的X和Y坐标,这似乎可以同时使用。

OSX Solution Code: OSX解决方案代码:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class ontopTest extends Application{

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(final Stage stage){
        Scene scene = new Scene(new Pane(new Label("test application")));
        stage.setTitle("Override OSX Menubar test");
        // Decorated window results in our window being placed below menubar even after setting window level to max.
        stage.initStyle(StageStyle.UNDECORATED);
        // An undecorated window fixes this and can be placed above the menubar.
        stage.setWidth(300);
        stage.setHeight(300);
        stage.setScene(scene);
        // stage.setAlwaysOnTop uneeded as com.sun.glass.ui sets window to top
        stage.setY(0); // Set Y Axis to 0
        // Need to show window first
        stage.show();
        // Print all windows running in current process
        System.out.println(com.sun.glass.ui.Window.getWindows());
        // Select which window to set level (window at index 0 in this case)
        com.sun.glass.ui.Window.getWindows().get(0).setLevel(3);
        // Set window level to 3 (Maximum)
    }
}

EDIT: Although I can confirm this works on Mac OSX Sierra, I have also tested this on Arch Linux w/ KDE Plasma and this method of setting the maximum window level does not work for that platform. 编辑:尽管我可以确认它可以在Mac OSX Sierra上工作,但是我也在带有KDE Plasma的Arch Linux上进行了测试,并且这种设置最大窗口级别的方法不适用于该平台。 It simply sets the window to 'AlwaysOnTop' mode but will still be forced underneath the KDE/X11 Menubar. 它只是将窗口设置为“ AlwaysOnTop”模式,但仍会被强制置于KDE / X11菜单栏下方。 The only solution I know of (so far) on how to bypass the X11 menubar on Linux systems is to use the wmctrl commandline X Window manager through entering the following commands: 我到目前为止(关于)如何绕过Linux系统上的X11菜单栏的唯一解决方案是通过输入以下命令来使用wmctrl命令行X窗口管理器

Add window to topmost level through selecting it by window title. 通过按窗口标题选择窗口,将窗口添加到最顶层。 This will also set the window to AlwaysOnTop 这还将把窗口设置为AlwaysOnTop

wmctrl -r "Window Title" -b add,above

Positioning the window (decorated or undecorated) to your desired (previously restricted) area, such as above the menubar, dock etc. 将窗口(装饰或未装饰)定位到所需的(以前受限制的)区域,例如在菜单栏,停靠栏等上方。

wmctrl -r "Window Title" -e 0,x,y,width,height

If you have a Java-based X11 Solution to setting undecorated windows above menubars/docks, please share! 如果您有基于Java的X11解决方案来在菜单栏/码头上方设置未修饰的窗口,请分享!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM