X11: frameless resizeable windows - linux

Can I have a frameless but resizeable window in X?
Setting just MWM_DECOR_RESIZEH without the other flags doesn't make it resizeable.
I can resize it myself manually but then I need to scrape for themed mouse cursors which are non-standardized and are also different for each corner and side.

There are exactly two ways to resize windows:
Leave it to the window manager and be happy. This is recommended way for X. If someone don't like it, he can install another WM that will make it better.
Make it by yourself - draw border around window, track the mouse cursor and when the user drags the edges - resize the window in a way you like. In this case you must set the override-redirect flag of the window and WM will not mess with it.

Related

How to snap a window to top/bottom half of screen

One of my favorite features in Windows is the ability to snap windows. [1]
With Windows 10 they can now be snapped to quarter-screen, as well as the left- and right-half screen available in previous Windows releases.
Is it possible to snap a window to top and bottom half?
In other words, snap a window to span the width of the monitor, but only half the height? It could be snapped to either the top or bottom of the screen.
https://support.microsoft.com/en-us/help/4027324/windows-10-snap-your-windows
Unfortunately no, not natively. See e.g.: https://answers.microsoft.com/en-us/windows/forum/windows_10-desktop-winpc/snap-assist-to-top-and-bottom-in-portrait-mode/3ecdd25e-8886-4ef1-a7db-0d2e168ce381.
There are third-party solutions, such as https://www.displayfusion.com/Discussions/View/portrait-mode-and-windows-snapping/?ID=8e0ff0b8-5988-43d9-bd54-4567d7869f48 and https://www.nurgo-software.com/products/aquasnap
This is now natively supported in Windows 11. Press Windows+Z, then you can select where you want your window to be. There are several other portrait-only layouts too (the spot that is dark blue is the one my mouse is hovering over):
Not in the way that you snap windows to the left and right; if you try to snap a window to the top by dragging it to the top of your screen it will just maximize that window...and dragging to the bottom won't work at all.
One way that I can think of that will work is minimize 2 windows that you want to split and resize them both so that they span the width of the screen and approximately half the height of the screen. Then drag each window to the desired portion of the screen. To make things easier, you might want to have the window that you want on the bottom of the screen open over the one that you want on top of the screen before you start minimizing windows.

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.

Missing pixels from upper left of window placed at origin

I have an application that uses a non-decorated window (no title bar and so on, it's eventually intended to be a full-screen application). It also has one-pixel-wide line images around the outside to form a natural border with the outside world.
When I run this application and the Window gets its default position (i.e., not at the (0,0) origin), the borders are clearly visible.
However, when I perform a this.Move(0, 0) in the constructor of the main window to make sure the window is positioned correctly, the upper-right pixels seem to disappear thus:
Ignore the Act text in that capture, it's actually the Activities menu under Gnome desktop. The actual upper-left pixel of the window is where those two red lines would meet.
Does anyone know what could be causing this issue? Is it possibly something to do with the Gnome Shell extensions taking control of that area?
The missing pixels are an artifact of the way gnome-shell does rounded rectangles for its windows.
If you really want to change it, you can edit the file /usr/share/gnome-shell/theme/gnome-shell.css. Look for the CSS selector .panel-corner and set -panel-corner-radius to 0px. This will cause the windows to have square corners rather than rounded ones. You will probably need to restart gnome-shell after making the change by pressing Alt-F2 and enter the r command.
Whether that edit will survive a gnome-shell (or even a theme) update is unsure, you may have to put into place something that keeps it at the value you want (or install an extension to do that for you).
That is how gnome-shell renders the top corners of the main monitor, it's a rounded corner, just not very visible with black on black. Changing this rendering is not something an application should do.
If your application is supposed to be full screen instead of just positioned at the corner, you could request gnome-shell to do that with Window.fullscreen(). Do not rely on always being full screen though: the window manager can decide otherwise.

How to deactivate window in Qt

I am trying to create a dockable window in Qt (it sits taking 4px width at the edge of the screen, always on top and it slides out when you hover it). I have to use WindowFlag BypassX11WindowManager (in order to hide taskbar hint, disable moving/resizing/etc. from window manager). I use these flags:
Qt::FramelessWindowHint
Qt::CustomizeWindowHint
Qt::X11BypassWindowManagerHint
Qt::WindowStaysOnTopHint
When I need my dock to be activated, I use the activateWindow() method. However, I have no idea, how to deactivate it.
Is there a way I can force my window deactivate? Now I can do it only by clicking another window and then return to the one that was active before revealing dock.
You should be able to use ->hide() to simply hide it if you don't want it to appear at certain points.
I assume, by the way, you know there is QDockWidget/ class that may help you as well. It's unclear from the above if you're using it or not.

Desktop effects (compiz) turned on: How to capture the image of a window WITH border/frame/title bar?

I would like to get the image of an X server Window (toplevel window, parent is the root Window) with its border/frame/title bar. I have already tried several libraries (Xlib, XRender, gdk, cairo) but none of them works. The captured image has the same geometry as the window but the frame is missing.
The problem is that the child window which should hold the frame image is InputOnly. The reason might be for this that the frame is rendered by the window decorator on the fly the same time as the Window itself.
I cannot capture the image from the RootWindow as the Window might be partially or entirely covered.
Redecorating the captured Window image could be an alternative.
Any suggestions? Thanks.
PS. When compiz is not running everything works as expected.
I use shutter for screen shots on linux, it's super easy to capture whatever portion of the screen you want. As a bonus, there are tools to add arrows or highlight sections.
http://shutter-project.org/preview/screenshots/

Resources