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

Implement window transparency to mouse events (#1236) #1568

Closed
wants to merge 1 commit into from

Conversation

rokups
Copy link
Contributor

@rokups rokups commented Sep 30, 2019

This is an implementation for window transparency for mouse events requested in #1236. There are some things to discuss before merging.

GLFW_MOUSE_PASSTHRU define and mousePassthru variable. I used terminology suggested in #1236. Naming is hard so if anyone has a better idea - speak up. Maybe we shuld do PASSTHRU -> PASSTHROUGH at least.

Is GLFW_MOUSE_PASSTHRU defined in appropriate place and is it's value proper?

I tried to add documentation comments but i did so without fully understanding what i am doing. In case anything is missing/incorrect please let me know.

libXext.so.6 - hope that ".6" is pretty much same across all distributions. I may be wrong.

CYGWIN - untested. Only reason why it would break is libXext-6.so being named something else i think.

Not sure if i got all _glfw.x11.xshape right.

Wayland while i think is implemented correctly - does not work. I tested with gears example, setting glfwWindowHint(GLFW_MOUSE_PASSTHRU, GLFW_TRUE); before window creation. It may be that kwin compositor does not have required bits for this to work. If anyone runs Gnome wayland - i would greatly appreciate if you could test this PR. Otherwise i may get around to setting up a VM for a test, but i would love to avoid it if possible.

X11/Windows/MacOS - everything works as expected.

@elmindreda elmindreda self-assigned this Feb 27, 2020
@elmindreda elmindreda added enhancement Feature suggestions and PRs input Keyboard, joystick or mouse macOS Wayland Windows Win32 specific (not Cygwin or WSL) X11 labels Feb 27, 2020
@elmindreda elmindreda added this to the 3.4 milestone Feb 27, 2020
@elmindreda elmindreda added this to Work queue in Queue Mar 2, 2020
@elmindreda elmindreda moved this from Work queue to Urgent in Queue Jun 11, 2020
@elmindreda elmindreda linked an issue Jul 3, 2020 that may be closed by this pull request
@elmindreda elmindreda moved this from Urgent to Now in Queue Jul 3, 2020
elmindreda added a commit that referenced this pull request Jul 9, 2020
elmindreda pushed a commit that referenced this pull request Jul 9, 2020
This adds the GLFW_MOUSE_PASSTHRU window hint and attribute for
controlling whether mouse input passes through the window to whatever
window is behind it.

Closes #1568.
elmindreda added a commit that referenced this pull request Jul 9, 2020
The client clip region was left in place when mouse passthrough was
disabled, leading to missing mouse input if the window grew beyond it.

Related to #1568.
elmindreda added a commit that referenced this pull request Jul 9, 2020
elmindreda added a commit that referenced this pull request Jul 9, 2020
Returning HTTRANSPARENT from WM_NCHITTEST does cause the window to be
transparent for some hit-testing APIs but does not make it pass mouse
input through to whatever window is below it.

For that to work on modern Windows, the window needs to be both layered
and extended-window-style-transparent.

Related to #1568.
elmindreda added a commit that referenced this pull request Jul 9, 2020
Platform code may not modify shared state.

Related to #1568.
elmindreda added a commit that referenced this pull request Jul 9, 2020
elmindreda added a commit that referenced this pull request Jul 9, 2020
elmindreda added a commit that referenced this pull request Jul 9, 2020
elmindreda added a commit that referenced this pull request Jul 9, 2020
@elmindreda
Copy link
Member

Thank you for this PR! My proposed changes are now in the mouse-passthrough branch of this repo. I didn't want to modify your commit without asking so I added a PASSTHRU to PASSTHROUGH rename pass for now.

Is GLFW_MOUSE_PASSTHRU defined in appropriate place and is it's value proper?

Yup, looks good! I modified the logic for the internal flag a little, to keep modifications of shared state inside shared code.

libXext.so.6 - hope that ".6" is pretty much same across all distributions. I may be wrong.
CYGWIN - untested.
Not sure if i got all _glfw.x11.xshape right.

The X11 path looks good and worked fine on X11 on both Linux and Cygwin. It needed a pre-fix because GLFW now loads all of Xlib dynamically, and there was an issue with not removing the custom input shape, but that was all.

I had to replace the Win32 implementation, though. While the WM_NCHITTEST method does what Dear Imgui docking needs it didn't match the passthrough behavior of other platforms and pass the input through. Instead the combination of WS_EX_TRANSPARENT and WS_EX_LAYERED is required, and for hidden windows also a call to SetLayeredWindowAttributes.

Wayland while i think is implemented correctly - does not work.

It seems to work perfectly in Weston. I've tried opaque windows and the gears example, setting it at creation or after.

The macOS path also just worked.

@elmindreda
Copy link
Member

I tested the mouse-passthrough branch with the current docking branch of Dear Imgui today and it appears to work as expected, i.e. the same as the current Win32 workaround in the demo code.

@rokups
Copy link
Contributor Author

rokups commented Jul 10, 2020

Thank you for looking into my PR.

I didn't want to modify your commit without asking

Please do whatever you think is necessary 👍

libXext.so.6 - hope that ".6" is pretty much same across all distributions. I may be wrong.

Google search sends mixed signals. Maybe it should be libXext.so instead?

@elmindreda
Copy link
Member

Google search sends mixed signals. Maybe it should be libXext.so instead?

That form of the name is typically only available if the development package is installed and may point to a library with a different ABI.

elmindreda added a commit that referenced this pull request Jul 15, 2020
The client clip region was left in place when mouse passthrough was
disabled, leading to missing mouse input if the window grew beyond it.

Related to #1568.
elmindreda added a commit that referenced this pull request Jul 15, 2020
elmindreda added a commit that referenced this pull request Jul 15, 2020
Returning HTTRANSPARENT from WM_NCHITTEST does cause the window to be
transparent for some hit-testing APIs but does not make it pass mouse
input through to whatever window is below it.

For that to work on modern Windows, the window needs to be both layered
and extended-window-style-transparent.

Additional logic changes to ensure mouse input passthrough, framebuffer
transparency and window opacity are mindful of one another when
modifying WS_EX_LAYERED.

Related to #1568.
elmindreda added a commit that referenced this pull request Jul 15, 2020
Platform code may not modify shared state.

Related to #1568.
elmindreda added a commit that referenced this pull request Jul 15, 2020
elmindreda added a commit that referenced this pull request Jul 15, 2020
elmindreda added a commit that referenced this pull request Jul 15, 2020
@rokups rokups deleted the mouse-passthru branch July 16, 2020 06:00
@ocornut
Copy link
Contributor

ocornut commented Jul 16, 2020

Thanks @rokups and @elmindreda for looking into this!

I had to replace the Win32 implementation, though. While the WM_NCHITTEST method does what Dear Imgui docking needs it didn't match the passthrough behavior of other platforms and pass the input through. Instead the combination of WS_EX_TRANSPARENT and WS_EX_LAYERED is required, and for hidden windows also a call to SetLayeredWindowAttributes.

One thought was coming to mind but then I realized it wouldn't meaningfully affect our use case. For the sake of completeneness I'm writing it down:

I haven't performed the tests yet, but I wonder if this might be altering performances of the swap/composition in any way. I guess we could do a quick test of running unthrottled with both settings and see if it makes any diffferences (worth testing with both variations of DXGI_SWAP_EFFECT_DISCARD and Win10 compositor friendly DXGI_SWAP_EFFECT_FLIP_DISCARD settings of the SwapChain). I will run those tests if I have time and report the info.

As Dear ImGui multi-viewports only temporarily enable this flags during dragging of a window the difference would likely not matter.

@ocornut
Copy link
Contributor

ocornut commented Jul 16, 2020

Results: Well, it turns out that just copying _glfwPlatformSetWindowMousePassthrough() into my Win32 main.cpp did the job.
I tested this in a DX11 setup with both DXGI_SWAP_EFFECT_DISCARD and DXGI_SWAP_EFFECT_FLIP_DISCARD with both Integrated Intel HD chip and Integrated Nvidia on same laptop and couldn't measure any meaningful difference, so you can nuke my thought above. At this point I can't pretend I understand how the WS_EX_TRANSPARENT and WS_EX_LAYERED flags behave, but I assume with the current settings they don't have any incidence on per-pixel compositing.

@elmindreda
Copy link
Member

Thank you for looking into it and posting the results!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Feature suggestions and PRs input Keyboard, joystick or mouse macOS Wayland Windows Win32 specific (not Cygwin or WSL) X11
Projects
Development

Successfully merging this pull request may close these issues.

Ignoring mouse events / transparent for inputs / disable hit testing
3 participants