I am making a web browser with gtk-rs. I am trying to do a check for fullscreen. I can get the screen size and compare that to the window size, if they are the same it is in fullscreen and I can hide the unnecessary widgets. Though this works, I can only get it to work when I bind it some key event (so when I press a key it will check if the window and screen sizes are the same again). I want to be able to get this to work by simply noticing the window size has changed.
Related
Is there a way to check if the root is visible (at least part of it is on the screen). I tried <tk.Tk>.winfo_viewable() and <tk.Tk>.ismapped() but both of them return True even if the window is fully hidden by another window. Checking if the window isn't focused wouldn't solve my problem.
I need it because I am working on improving this that uses <tk.Tk>.overrideredirect(True) to remove the title bar. The problem is that I can't Alt-Tab to the window so I want to call <tk.Tk>.overrideredirect(False) each time the window isn't (at least partially) visible.
I want my application to handle resizes on its own. Is there a way to stop the window manager from resizing my window during a resize event but still receive those events. EG: The window manager tells the window what the dimensions should but it is up to my application to actually perform the resize. I want resizing to behave more like wayland where it is the client who is responsible for the window.
No you can not get configure notification events when there is no configuration change to your window.
If you want to do this you will need to draw your own size grips and listen for button click and/or drag events and write code to resize your window from there.
I would like to be able to toggle between framed and frameless window in my Electron app, without needing to construct a new window. This is because this option is a different view than what would be initially loaded, therefore it would be nice if there is a way to change the current window to be frameless.
I have found window.setFullscreen() for toggling between full screen mode. I've not been able to find anything similar for frameless window. Is there any such method or workaround that I'm not seeing?
As the docs go, you enable or disable window frame at the time of creation of browser window. After that, there are no methods you can call to enable or disable frame. However, if you really really want that option, there may be a workaround. And a workaround, is well, a workaround.
Create 2 browser windows, one over the other. The first one being transparent window(with frame and click-through) and the second one being your content window(without frame).
Implement your custom solution to keep size and position of both the windows in sync. Use ipc to share data between the windows.
Toggle the visibility of the transparent browser window to show/hide frame.
Some relevant resources:
Creating frameless window : https://electronjs.org/docs/api/frameless-window#create-a-frameless-window
Creating transparent window : https://electronjs.org/docs/api/frameless-window#transparent-window
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.
We have this Flex app built on Builder 3 and we're using SuperTabNavigator from FlexLib to have some modules displayed. The thing is, whenever the user resizes the browser window all the contents on any tabs open simply disappear and there's no way to get them back. This only happens the first time, so if you close these 'broken' tabs and reopen them, you can resize all you want, but you still lost all you were doing in them and this is unacceptable. I've done some testing and found the module in that tab doesn't dispatch the resize events when this happens. It's dispatched when it opens (everything is set to 100% to fit the browser window, so it resizes on startup) and every other time you resize it without 'breaking' it. It gets weirder. I've also found that resizing works perfectly as long as you resize it to a size larger than the original (i.e. you open it in a browser window that is restored and then maximized), but even after doing that, if you change its size back to something even a pixel smaller than the original, the module just disappears. Everything else remains in perfect working conditions: any components outside tabs and the tabs itself work, but (summing up) anything within any tab open at the moment you first resize the browser window to a size smaller than the original just disappears.
I understand that this is a weird problem and hope some of you might be able to help me. Feel free to ask any questions if anything wasn't clear.
Thanks in advance.
I had this exact same problem with my application. The issue stemmed from the fact that the RemovedFromStage event was being fired when the window was sized smaller than its original size. I was catching the RemovedFromStage event and hiding my component, which resulted in this behavior. A more detailed explanation can be found here.