smithay icon indicating copy to clipboard operation
smithay copied to clipboard

Consider setting `_JAVA_AWT_WM_NONREPARENTING=1` in xwayland

Open i509VCB opened this issue 4 years ago • 7 comments

My testing by running some of the intellij ides inside the winit backend shows that for some reason no elements in swing are rendered. Setting _JAVA_AWT_WM_NONREPARENTING=1 fixes this issue since Java AWT/Swing seems to attempt to detect what window manager is in use and adjusting it's behavior based on that. However java assumes re-parenting in the scenario that you are not using compiz, lg3d or cwm.

Relevant source from openjdk: https://github.com/openjdk/jdk/blob/739769c8fc4b496f08a92225a12d07414537b6c0/src/java.desktop/unix/classes/sun/awt/X11/XWM.java#L610-L611

@psychon you probably know the best course of action here.

i509VCB avatar Oct 04 '21 06:10 i509VCB

Can Smithay pretend to be one of those three? That would be much more robust than setting an env var.

DemiMarie avatar Oct 04 '21 06:10 DemiMarie

I would consider setting the environment variable to be the responsibility of a desktop environment build with smithay. We could set it in anvil though.

Overriding _NET_WM_NAME on the other hand is something we can enable, although I am not sure, if that is a good idea.

Drakulix avatar Oct 04 '21 06:10 Drakulix

you probably know the best course of action here.

Is "don't support Java apps" an option? They are always a pain.

Edit: Since this is the internet, I'll better be explicit: The above is supposed to be a joke. It's just that I already got too many bug reports involving Java.

Relevant source from openjdk:

Wow, I needed way more Java-related bugs before I dared looking the first time into Java's source code. I did that once and then never dared to do so again. Java is doing the wrong things on purpose. Someone once told me that the relevant code is older than the X11 standards. As if that were an excuse for not following the standards...

In the end, one of the reasons I made AwesomeWM a reparenting WM (even for people who don't want titlebars) was "Java being broken".

Can Smithay pretend to be one of those three?

I think Java gets the kind of WM from a root window property that is specified in EWMH. Hm. xprop -root says that this must be _NET_WM_NAME, but that's not actually specified in EWMH. Instead, EWMH says that the window in _NET_SUPPORTING_WM_CHECK should have _NET_WM_NAME: https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm46515148903664

Anyway, this seems to be the function that you need to convince: https://github.com/openjdk/jdk/blob/739769c8fc4b496f08a92225a12d07414537b6c0/src/java.desktop/unix/classes/sun/awt/X11/XWM.java#L744

Another idea: What does wlroots do? And weston?

psychon avatar Oct 04 '21 07:10 psychon

Okay, so wlroots wants people to set _JAVA_AWT_WM_NONREPARENTING: https://github.com/swaywm/wlroots/issues/1626 https://github.com/swaywm/wlroots/issues/1464

(By the way, what does this environment variable do? Java on purpose ignores all X11 events until it gets a ReparentNotify. So, it does not render its windows because it just ignores the requests to do so.)

Weston seems to use a reparenting WM: https://github.com/wayland-project/weston/blob/eff793ab46f1e93a5a76ab985abb4c27ff0eb0ed/xwayland/window-manager.c#L1121

(Edit: And weston also seems to draw titlebars / window decoration via X11. That way it basically gets "client side decoration" over the wayland protocol, even though it drew the decorations itself. That might simplify some stuff, but since "server side decoration" is a thing these days, it might not be that important. This code seems to be from 10 years ago where AFAIK CSD was the only option.)

(What is a reparenting WM? The WM creates its own X11 window and then reparents the application's window from the root window to this new window. This can be used to make the WM's window slightly larger. This extra space can be used for titlebars. Hence, "basically everything" out there is a reparenting WM, but there are some slight exceptions. This makes it very easy to write code that only works with reparenting WMs.)

psychon avatar Oct 04 '21 07:10 psychon

(By the way, what does this environment variable do? Java on purpose ignores all X11 events until it gets a ReparentNotify. So, it does not render its windows because it just ignores the requests to do so.)

Looks like the environment variable is an override to force java to behaves assuming it has a non-reparenting WM, the code linked by @i509VCB reads as:

static boolean isNonReparentingWM() {
        if (awtWMNonReparenting == -1) {
            awtWMNonReparenting = (XToolkit.getEnv("_JAVA_AWT_WM_NONREPARENTING") != null) ? 1 : 0;
        }
        return (awtWMNonReparenting == 1 || XWM.getWMID() == XWM.COMPIZ_WM
                || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM);
}

elinorbgr avatar Oct 04 '21 11:10 elinorbgr

Just for the completeness sake. There seems to be some work done to add Wayland server support: https://openjdk.java.net/projects/wakefield/index.html

Exidex avatar Oct 13 '21 15:10 Exidex

@Exidex yep I've seen Wakefield and I am in the client libraries mailing list.

i509VCB avatar Oct 13 '21 16:10 i509VCB

smithay has a reparenting Xwm now. We don't need this flag.

Drakulix avatar Mar 10 '23 11:03 Drakulix