Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nxagent: Pass down if window manager has been detected #830

Open
wants to merge 1 commit into
base: 3.6.x
Choose a base branch
from

Conversation

uli42
Copy link
Member

@uli42 uli42 commented Aug 9, 2019

At start a rootless nxagent checks if the real X server has a Window
Manager running. It uses a standard detection routine that tries to
select a special input (SubStructureRedirect). As only one client per
X server is allowed to select that input one can deduce from the
success of this operation if a Window Manager is running.

If nxagent is run in rootless mode and has not found a Window Manager
on the real X server it will grab all input (see
Screen.c:nxagentOpenScreen).

If any client of the nxagent runs the standard Window Manager
detection routine against a rootless nxagent it will not see the
Window Manager. If this client happens to be a rootless nxagent again
it will then grab all input which is undesired here. Other clients
might do other undesired stuff in that case.

To avoid all that a rootless nxagent now tries to detect if a client
runs that detection routine and returns the result of its own check to
the client.

@uli42 uli42 requested a review from sunweaver August 9, 2019 09:34
Copy link
Member

@sunweaver sunweaver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this approach of hacking nxagent code paths into the the DIX. See my inline comments.

Please get back to me, if you have any questions about my reasoning.

Thanks,
Mike

EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask)
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this one. EventSelectForWindow is called from within ChangeWindowAttributes (in dix/window.c). ChangeWindowAttribute is a method set in the pScreen struct. We do define pScreen->ChangeWindowAttributes in Screen.c and assign nxagentChangeWindowAttributes (Window.c) to it. In nxagentChangeWindowAttributes we call XChangeWindowAttributes after doing some nxagent magic.

So, on what code path is the above EventSelectForWindow function really called insider nxagent? I feel that we should handle this a bit more object oriented, that is: define an nxagentEventSelectForWindow and have that called from whereever. Also, I'd prefer to see dix/events.c patched in a way, that ChangeWindowAttributes calls nxagentEventSelectForWindow if NXAGENT_SERVER is defined, EventSelectForWindow (from X.Org), if not defined.

extern Bool nxagentWMIsRunning;

int
EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please rename to nxagentEventSelectForWindow and let it be called from whereever needed.

@uli42
Copy link
Member Author

uli42 commented Aug 10, 2019 via email

@uli42
Copy link
Member Author

uli42 commented Aug 10, 2019

Here's the according backtrace:

(gdb) bt
#0 EventSelectForWindow (pWin=pWin@entry=0x555555b71bb0, client=client@entry=0x555555ca1e20, mask=1048576) at NXevents.c:529
#1 0x000055555559d7c0 in ChangeWindowAttributes (pWin=pWin@entry=0x555555b71bb0, vmask=2048, vlist=vlist@entry=0x555555ca1ffc, client=client@entry=0x555555ca1e20) at ../../dix/window.c:1291
#2 0x00005555555b3822 in ProcChangeWindowAttributes (client=0x555555ca1e20) at ../../dix/dispatch.c:525
#3 0x00005555555bae98 in Dispatch () at NXdispatch.c:476
#4 0x0000555555599cb1 in main (argc=4, argv=0x7fffffffdd18, envp=) at main.c:353

Note that nxagentChangeWindowAttributes is not called at all! dix's ChangeWindowAttributes calls nxagentChangeWindowAttributes at the end, but EventSelectForWindow is called before.

This is all internal functionality so we need to intercept that somehow. It is just the same as most other call interceptions we do.

Uli

Update: pasted the correct backtrace...

@uli42
Copy link
Member Author

uli42 commented Aug 10, 2019

After having another look: while we could check all this nxagentChangeWindowAttributes we could not return a result because ChangeWindowAttributes calls it without any rc check. So we have these alternatives:

  1. patch dix/window.c:ChangeWindowAttributes (we don't want that)
  2. replace ChangeWindowAttributes by an own function
  3. patch EventSelectForWindow (that's what I did). It is only called from ChangeWindowAttributes.

@sunweaver
Copy link
Member

sunweaver commented Aug 10, 2019 via email

@uli42
Copy link
Member Author

uli42 commented Aug 10, 2019 via email

@uli42
Copy link
Member Author

uli42 commented Sep 1, 2019

You have not responded to my explanations. So what are we going to do with this PR?

@sunweaver
Copy link
Member

  1. replace the whole function via Xorg_ rename and adding another
    function named as the original on, possibly calling the renamed Xorg_
    variant at some point. This is the approach I favour now as it helps
    in reducing code duplication. Also we can update dix code and
    automatically benefit from upstream changes without touching our own
    code. Further, and most important, it greatly reduces the comparison
    work that's required when backporting upstream Xorg code.

I prefer variant 2., then...

@uli42
Copy link
Member Author

uli42 commented Apr 16, 2020

Currently I do not recommend to merge this. It turned out that java applications in a rootless session struggle with their window manager detection and will then fail to resize properly (window gets bigger, but not content). A workaround is to run them with _JAVA_AWT_WM_NONREPARENTING=1

I think the trick that would fix it was to propagate the root window properties _NET_SUPPORTING_WM_CHECK and _NET_WM_NAME, too. Or set them explicitly like wmname does (https://git.suckless.org/wmname/file/wmname.c.html).

Update: just verifified: using wmname to set the WM to "LG3D" (wile the local side isr running KWin) makes java apps work again. But I am unsure if we can set that regardless of the local window manager.

@sunweaver
Copy link
Member

Currently I do not recommend to merge this. It turned out that java applications in a rootless session struggle with their window manager detection and will then fail to resize properly (window gets bigger, but not content). A workaround is to run them with _JAVA_AWT_WM_NONREPARENTING=1

I think the trick that would fix it was to propagate the root window properties _NET_SUPPORTING_WM_CHECK and _NET_WM_NAME, too. Or set them explicitly like wmname does (https://git.suckless.org/wmname/file/wmname.c.html).

Update: just verifified: using wmname to set the WM to "LG3D" (wile the local side isr running KWin) makes java apps work again. But I am unsure if we can set that regardless of the local window manager.

ok. Thanks for the heads up.

At start a rootless nxagent checks if the real X server has a Window
Manager running. It uses a standard detection routine that tries to
select a special input (SubStructureRedirect). As only one client per
X server is allowed to select that input one can deduce from the
success of this operation if a Window Manager is running.

If nxagent is run in rootless mode and has not found a Window Manager
on the real X server it will grab all input (see
Screen.c:nxagentOpenScreen).

If any client of the nxagent runs the standard Window Manager
detection routine against a rootless nxagent it will _not_ see the
Window Manager. If this client happens to be a rootless nxagent again
it will then grab all input which is undesired here. Other clients
might do other undesired stuff in that case.

To avoid all that a rootless nxagent now tries to detect if a client
runs that detection routine and returns the result of its own check to
the client.
@uli42 uli42 force-pushed the pr/pass_down_wm_presence branch from cb87f01 to eeade65 Compare June 9, 2021 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants