Qt window moves even when intercepting mouse events - linux

I have a Qt OpenGL (with qt 5.5) Application in which you can click to drag objects in a 3D scene.
This is implemented by having a subclass of QOpenGLWidget which overrides mousePressEvent, mouseReleaseEvent and mouseMoveEvent.
However, when I drag an object, I can move it for one frame before the window starts activating the window move mode, and my mouse movements actually start moving the whole window, as if I was dragging the title bar.
I suspect there is a conflict between the application and my window manager (kwin 5.4.3), but I don't know where to look at to debug this issue and whether it's my application's fault or if I have to fix my window manager.

You may need to call the accept() method of the event you are handling.

Related

Neutralino.window.setDraggableRegion is malfunctioning on windows

What happens is that I initiate the window drag instruction with Neutralino.window.setDraggableRegion, it works but there is a very big problem in rendering.
I am on a windows system. Here is a video of the problem:
Video of the problem
As you specified, the window is dragging but the mouse doesn't move with the point you click on, instead the mouse is at a different position.
I Looked at how draggable region function works under the hood, and it's handled by the JavaScript Client File, by setting the window position to the amount of mouse has moved on x and y.
since the mouse pointer doesn't move instead the window moves relative to the position from where you started clicking.
I will raise this issue, and soon a fix for this will be out!
Issue has been raised

Is there any difference between double-click the window's title bar and click the window's maximize button?

I find a pretty weird bug while using the imgui dx12 example. When I double-click the window's title bar to maximize the window, the program failed in recreating the command allocator. But click the window's maximize button or resize the window is ok. The graphics driver might cause this problem, because it only happens when I run the program with the integrated intel graphics card.
At the Win32 API level, double-clicking on the non-client area (the title bar) causes a WM_NCLBUTTONDBLCLK, whilst the maximise/resize will cause a WM_SYSCOMMAND.
If neither is processed by the client, the system will perform default behaviour and issue a WM_SIZE to inform of the action.
What ImGui does with these events I cannot tell you.

Mouse gets stuck in "drag and drop mode" when I break into the debugger during a drag and drop operation

I have this weird problem. I'm writing a GUI app in Qt and I have a crash during a drag and drop operation. If I run this app in a debugger, then when this crash occurs and the app breaks into the debugger, the mouse cursor gets stuck in "drag and drop mode" and I can't click on anything until the app is killed. How can i get around that?
Your app crashes in a GUI thread. Try to move the operations you are doing there to a new thread.
On your DragDrop event:
start a new thread doing your job
return from your event without waiting for results
I have the same issue.
I found that when a breakpoint was hit when mouse is dragging or mouseDown, GUI will get stuck and mouse will become unable to response.
For example:
A. Drag&Drop
1) Eclipse SWT: create Drag and Drop for a control
2) set breakpoint within dragging
B. Mouse Down & Mouse Up
1) use mouse down / mouse up to implement behavior of Drag&Drop
2) set breakpoint to dragging action/mouse moving
The mouse will stuck when breakpoint occurred, no matter which DnD happened.
To get mouse back, I'll need to use CTRL+ALT+F1 and use command to kill my process.
Perhaps working in VM or remote desktop can get rid of it.

How to make an overlay which capture no events

I would like to draw some sort of window on top of all the other windows. For example, to display some debugging infos (like conky) or things like a timer.
The main thing is that I would like to able to continue using the other windows while using it (the events go through transparently).
I've tried doing it with pygtk, pyqt and others but can't find a way to make it a real overlay with no event capture.
Is there some low-level x11 solution?
I think the Composite-extension-approach will not work when a compositing manager is running (and thus Composite's overlay window is already used).
Since you explicitly mention "no event capture":
The SHAPE extension allows to set some different shapes for a window. Version 1.1 of this extension added the "input" shape. Just setting this to an empty region should pretty much do what you want.
Some concrete example of exactly what I think you ask for can be found in Conky's source code: http://sources.debian.net/src/conky/1.10.3-1/src/x11.cc/?hl=769#L764-L781
Edit: Since you said that you didn't find anything in Gtk (well, PyGtk), here is the function that you need in Gtk: https://developer.gnome.org/gdk3/stable/gdk3-Windows.html#gdk-window-input-shape-combine-region
You might need Composite extension + GetOverlayWindow request:
Version 0.3 of the protocol adds the Composite Overlay Window, which
provides compositing managers with a surface on which to draw without
interference. This window is always above normal windows and is always
below the screen saver window. It is an InputOutput window whose width
and height are the screen dimensions. Its visual is the root visual
and its border width is zero. Attempts to redirect it using the
composite extension are ignored. This window does not appear in the
reply of the QueryTree request. It is also an override redirect
window. These last two features make it invisible to window managers
and other X11 clients. The only way to access the XID of this window
is via the CompositeGetOverlayWindow request. Initially, the Composite
Overlay Window is unmapped.
CompositeGetOverlayWindow returns the XID of the Composite Overlay
Window. If the window has not yet been mapped, it is mapped by this
request. When all clients who have called this request have terminated
their X11 connections the window is unmapped.
Composite managers may render directly to the Composite Overlay
Window, or they may reparent other windows to be children of this
window and render to these. Multiple clients may render to the
Composite Overlay Window, create child windows of it, reshape it, and
redefine its input region, but the specific arbitration rules followed
by these clients is not defined by this specification; these policies
should be defined by the clients themselves.
C api : XCompositeGetOverlayWindow
PyGTK Solution:
I think the composite and shapes X extensions are sufficiently ubiquitous and shall assume here that they are active on your system. Here's PyGtk code for this:
# avoid title bar and standard window minimize, maximize, close buttons
win.set_decorated(False)
# make the window stick above all others (super button will still override it in the z-order, which is fine)
win.set_keep_above(True)
# make events pass through
region = cairo.Region(cairo.RectangleInt(0, 0, 0, 0))
my_window.input_shape_combine_region(region)
win.show_all()
# set the entire window to be semi-transparent, if we like
win.set_opacity(0.2)
Basically what this does is tell Gtk that other than pixel (0,0) the entire window my_window should not be considered part of itself in terms of event propagation. That in turn, according to my current understanding means that when the pointer moves and clicks, the events go to the underlying window under the pointer position, as if my_window was not there.
Caveat:
This does allow your overlay window being the focus window (due to user-solicited window switching or just because it pops up and gets the focus when your application starts). Which means that for example, keyboard events will still undesirably go to it up until the user has clicked through it to make it lose focus in favor of whatever window is under the cursor. I would likely use the approach described here to iron out this aspect.
If there's a different and proper approach for making a portion of the screen "display stuff but not receive events", without building an oddball window like above over it, I'm happy to learn about it.
I assume that one's particular desktop environment (gnome, unity, etc. on linux) may interfere with this solution depending on version and configuration, on some occasions.

How to grab the pointer on Wayland like Gnome does?

It specifically says in the Wayland TODO text file that Wayland doesn't have active grabs for the pointer yet. But if I run Gnome on Wayland, try clicking a menu open and then clicking outside it, the outside click is swallowed as if the pointer was grabbed by the menu window. How does Gnome manage that?
What you are talking about can be done very easily by creating a transparent overlay over the entire screen. In that case, the click events on the transparent region will not propagate to the underlying elements. You can see this in Telegram's image viewer, where it creates a full-screen gray overlay under the image.
But on the compositor side this effect can be achieved in a different way-- by disabling all input events outside the popup rectangle.

Resources