Zoom on Linux: simple X11 windows can't be shared - linux

I'm using the Zoom video conference system on Ubuntu 20.04 with Gnome and X11 (not Wayland).
I wrote an application which directly uses X11 instructions (XCreateSimpleWindow()) to open a window. This window cannot be shared on Zoom; it simply doesn't appear on the list of windows that can selected for sharing (my terminals, editors, web browsers appear in the list). It can be shared with "Share Screen Portion", though.
Does anyone know what qualities a window must have such that it can be shared in Zoom? Does my code have to register the window with some Linux / Gnome instance? Are there any requirements for event handling in my application?
Thanks a lot for your help!

I think, I found a solution. Apparently, Zoom only considers a window for sharing if the X11 property _NET_WM_NAME is set. Here's how I do it from C++ (plain X11 code):
// set _NET_WM_NAME: without this, the window is not visible for Zoom screen sharing
// from https://gist.github.com/mattn/105615
Atom net_wm_name_atom = XInternAtom(dsp, "_NET_WM_NAME", 0);
Atom utf8_string_atom = XInternAtom(dsp, "UTF8_STRING", 0);
const char *net_wm_name = "something";
XChangeProperty(dsp, win, net_wm_name_atom, utf8_string_atom, 8, PropModeReplace,
(unsigned char*) net_wm_name, strlen(net_wm_name));
// map window to screen
XMapWindow(dsp, win);
Now the window is no longer invisible for Zoom which means it appears in the list of windows which can be selected for screen sharing.

Related

Window manager for linux, supporting focusless windows

On my arm embedded device with a touchscreen, I have a 3rd party program (program A), that creates a window which handle keyboard presses. Because of that, this window always has to have focus. This is a closed source, and I do not have options to modify it.
I need to create a window in linux, that never grabs focus. It just shows an image, some times full screen. However, I have options not to make it full screen (1 pixel less, so window below is visible.).
Right now, I am using only X server, but I can install (almost) any window manager.
Is there a way to create a window in X, that never gets focus? If I understand X correctly, a window bellow mouse will get focus.
Is there a window manager, which supports such feature?
Is this possible to do with with xcb or wayland?
On Wayland, it's up to the compositor to tell the client whether it has focus or not, and which surface(s) to send key events to. So it would depend on the compositor or compositor toolkit you're using if it's possible.
KWin has an option that sounds like it does what you want. Right click the window title bar and choose more actions -> special window settings -> accept focus
Of the compositor toolkits, I only know the Qt Wayland Compositor API, and with that it should be possible (assuming your application can run as a Wayland client). The easiest thing would be to just show the image in the compositor using the QML APIs, or you could set enabled: false on the WaylandQuickItem or ShellSurfaceItem that you don't want to grab input focus.

With Qt under Gnome 3, Xfce and Unity a full screen window with a child window doesn't stay on top

I have a full screen application based on Qt. Full screen applications should always be on top because otherwise part of the window will be obstructed. I want the frameless full screen window to have child windows (special dialogs, ..). These child windows should be shown on top of the full screen window. Not much sense in showing them below.
A short, self contained example is:
from PySide import QtGui, QtCore
app = QtGui.QApplication([])
window = QtGui.QWidget(f=QtCore.Qt.WindowStaysOnTopHint)
child_window = QtGui.QWidget(window, f=QtCore.Qt.Window)
child_window.resize(400, 300)
layout = QtGui.QVBoxLayout(window)
exit = QtGui.QPushButton('Exit')
exit.clicked.connect(app.exit)
layout.addWidget(exit)
create = QtGui.QPushButton('Create child window')
create.clicked.connect(child_window.show)
layout.addWidget(create)
layout.addStretch()
window.showFullScreen()
app.exec_()
It's written in Python and tested on Python 3.X + PySide 1.2.2 (Qt 4.8) + Ubuntu 14.04 (Unity desktop) or Windows 7. However transformation to C++ Qt (or PyQt) should be straightforward.
The observation is that on Windows everything is as described at the beginning. The Qt.WindowsStaysOnTopHint is not necessary, while on Ubuntu it is.
On Ubuntu I see that initially the full screen main window is on top of everything but as soon as a child dialog window is created the usual desktop decorations (top and left bars) are shown above the full screen main window obstructing part of the view! As soon as the child window is closed the full screen window is on top again.
Question is now if there is anything that can be done to have a full screen window which is on top plus child windows on Ubuntu and with Qt?
The different behavior between Windows and Linux is also not satisfying because OS specific code should be avoided if possible.
Later:
Using the overview of available desktop environment on Ubuntu I installed several environments and tested them.
KDE, Lubuntu (Lxde?) and Openbox work as expected (and equally to Windows). The main window stays on top when shown full screen and child windows are displayed above.
However for Gnome-Shell (Gnome 3), Xfce, Unity and Awesome the desktop decoration stays on top of full screen mode windows of children windows are displayed also. Xfce and Unity behave exactly equal, Gnome and Awesome have even some small additional problems.
Did you tried thing which documentation suggests?
Qt::WindowStaysOnTopHint 0x00040000 Informs the window system that the window should stay on top of all other windows. Note that on
some window managers on X11 you also have to pass
Qt::X11BypassWindowManagerHint for this flag to work correctly.
Another thing why you want other window to be a child if it you what to be under a parent?

How can I create an X window/client that is on top of all other windows, not under WM control and has no input? (overlay, OSD)

I want to write applications (or use existing ones, that would be even more convenient) that behave like a hardware screens OSD (on screen display), only without input.
That is: A graphical output (e.g. from a GUI toolkit like Qt or Gtk) is placed on a layer where it is above even fullscreen-windows like Firefox F11 mode or a video player in fullscreen mode. That includes "above" the mouse cursor as well, so technically and graphically the mouse cursor would move below this widget.
I don't know about real fullscreen applications with SDL or OpenGL though, but this is not the requirement. If you know this as well please include it in your answer.
Real world applications are read-only overlays like a little webcam window, a TV-station like logo or premade annotations. So all in all this is meant for live presentations, streaming and recording of screencasts and tutorials with minimal post processing.
My own hacked, unsuccesful, experiments showed at least that removing this window from the WM control ( I did this by choosing a GTK popup dialog instead of a real main window) lets you position in absolute coordinates and it will ignore things like virtual desktops and workspaces, which is good, so you can switch between those and the overlay/HUD will stay in place.
Of course this cannot be done in software with the same Z-value (top/bottom windows) as the hardware screen. So technically I am talking above all other windows but below the screensaver or lock-screen layer.
+1 internet for linking to docs and giving the right keywords.
+2 internet for a working code example, language, gui-toolkit etc. doesn't matter.
You probably need composite overlay window from Composite extension - see section 3.2 "Composite Overlay Window" extension docs. (cursor is above this window)
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.
Example using node-x11:
var x11 = require('x11');
x11.createClient(function(err, display) {
var X = display.client;
var root = display.screen[0].root;
X.require('composite', function(err, Composite) {
Composite.GetOverlayWindow(root, function(err, overlay) {
// already automatically mapped here:
//
// 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.
});
});
});

Different QWidget behaviour on Windows and Linux

QWidget is created after some time in my app. I start my app. Then I use internet browser. On Linux my new widget appeares over my browser, but on Windows - not. Widget has parent widget. How to fix it on Linux?
both parent and my widget have only setFocusPolicy(Qt::StrongFocus); The Linux OS is Xubuntu. And one difference in parent class:
#if defined(Q_WS_X11)
setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
#else
setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
#endif
I believe Windows prevents other programs from stealing the focus while some other OS may not enforce that.
When you create your widget, you should set the window state before making it visible.
For instance
QWidget* lateWidget = new QWidget(this); // or add to layout or whatever
lateWidget->setWindowState(this->windowState());
lateWidget->show();
Edit:
From the docs :
A widget that happens to be obscured by other windows on the screen is
considered to be visible
Which means that if you open the browser on top of parent then lateWidget->show() will ask to the window system to be activated.lateWidget which then pop on top and gain user mouse and keyboard focus.
before showing lateWidget a quick fix is to use
lateWidget->setAttribute(Qt::WA_ShowWithoutActivating);

Click events in linux using opencv

I am doing a project to control mouse events by hand gestures using opencv in linux. I am able to control the mouse pointer with my hand movements.
I have achieved counting the number of fingers in the hands. I want to trigger mouse events depending upon the number of fingers shown. In windows there is a function mouse_event. But i am working in linux.
If there is any function for click events in opencv(linux) please let me know. Also help me with the header files to be included for those functions.
Thanks in advance!!
You can use Xlib library for handling mouse events in Linux environment. Xlib is an XWindow System protocol library. It contains functions for interacting with an X server. Main advantage of using Xlib in you project is that, you can handle mouse events globally( throughout the desktop, or in other window, not locally in your application window ).
Check out Xlib-MouseClick.
Just call the function mouseClick() in your program with argument -
0 - for left click,
1 - for middle click, and
2 - for right click, at current position of mouse pointer.

Resources