Closed Mis012 closed 1 year ago
Surprised there's not already an issue for this. It's definitely something I have my eye on. gdk_wayland_window_set_use_custom_surface ()
has been removed in GTK4, which makes the current approach this library takes impossible. That being said, it only works on GTK3 due to a lot of terrible hacks (and I'm going to need to add more to fix #9). We have a few options for GTK4:
Since GNOME doesn't support or want to support Layer Shell, I highly doubt this will happen. Even if they would consider this, I'm not sure it's a good idea. Not going to pursue it.
If we could get some APIs landed in GTK4, we could easily port over and other similar projects would benefit as well. I've tried in the past and received some pushback. They see these sort of features as out-of-scope, and don't want to be stuck maintaining and testing a large stable API surface area.
However, another reason my previous attempts failed might have been that I was changing the architecture in a way that conflicted with plans they already had (which I didn't fully understand). If I take another look in the future (once the major GTK4 surface changes are all in place), there might be a less controversial way to get the features I need.
It might be feasible to use the system GTK4, but replace large parts of GDK with our own patched versions. Well see how much we'd have to copy once GTK4 settles down. Of course we would be heavily depending on unstable GDK internals, but there might still be ways to work with multiple versions of GTK. There would also be licensing issues, but there are various workable solutions to them.
A soft fork of GTK in its entirety would be annoying to maintain, annoying to build and wouldn't benefit from distro-specific patches (at least not without more trouble). Still, it's an option that would make all our API problems go away.
This is one of my more wacky ideas. I could build a library that creates a proxy Wayland client and server, and allows intercepting and changing messages on the wire. This could be used to implement GTK layer shell, and also a lot more. You could switch between any shell protocol (wl_shell, xdg_shell, layer_shell, etc) regaurdless of toolkit. You could even run normal apps as layer shell clients without recompiling them. I'm pretty sure this is possible, but idk how difficult it would be. It largely depends on if libwayland could be used, or if it would have to be forked/reimplemented.
I've been whacking at #9 whenever I have the time, and fixing that one way or another is my next job on this project. Once that's done, I'll look into options 2 and 3. Might pursue option 5 on the side (because it's a cool idea), or maybe only if all else fails.
Realistically, probably many months before GTK4 support, if ever. If you have (or acquire) a decent understanding of GDK internals and Wayland and want to make it happen faster, let me know and I'll point you in the right direction.
I think the hackiness is a bigger issue than licensing concerns, as long as it's all nice LGPLv3 and there is no requirement for static linking... if you're using GTK, you're clearly fine with linking against LGPL libs
I think that 1 would be nice if they allow external maintainership, since you could take care of maintenance for them and you would not need to worry about ABI stability
may be too organizationally complicated though
I don't like 1 because it makes every feature/fix an ordeal involving the GTK maintainers, and we have to start from square 1 if we want to support any new protocol. 1 is also sort of irrelevant because they are almost certainly not going to allow it.
Is there already a decision how to go on? I'm using gtk-layer-shell for some of my private projects (and porting it to Gtk 4 is on the todo list).Sadly I do not yet have deeper knowledge of Gdk itself, thats honestly one level to complex for me.
For reference: This issue at Gtk. (But nothing going on there at the moment).
I haven't made any moves toward GTK4 since the previous comments. That is indeed the relevant GTK issue. Next step is to look at the current state of GTK4, and see if a suitable custom Wayland surface type can be added as jadahl
suggested over there. If a reasonable implementation is possible, it needs to be written and PRed (this would be option 2 in the list above). Getting that in is the ideal route, and if it doesn't work or they reject it we'll have to go for another option.
@wmww for path 3, we can just now rely on mapped, and replicate gdk_wayland_surface_set_custom_surface as a hook. (we need knowledge about impl->mapped private variable then) And I think this will work.
Now that GTK4 released, which options are the most viable?
My next step is to make a stab at option 3. Hopefully I'll be able to get it to work without introducing too much fragility. Some updates since my July post:
Currently no timeline as to when I'll do this.
I've started work on option 3 (porting without upstream changes). Looks like it's probably going to be possible. Initial proof-of-concept works. Code is messy, incomplete, and there's no popup support yet. WIP branch: gtk4
.
It's always going to be somewhat fragile (and some work to maintain) until GTK gets enough patches to completely remove the need for gtk-priv
. https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2992 shows promise of moving in this direction. Please let me know what you need GTK4 support for and when. I'm probably not going to start making releases for GTK4 until people actually need it in distributions.
Just a heads up that the GTK4 branch is not working at the moment, because the size-allocate signal got removed from GTK. I got it to run with (more or less) just replacing all the instances of size-allocate with realize but obviously that's not really a good way to do it.
Yeah, IIRC the state I left the branch in was very much not ready. It sounds like you may have gotten farther than me. Is your branched pushed somewhere?
Not right now sorry. I just tried to redo what I have done but I seem not to get it working again.
I'll try again if I find the time.
I need it in order to switch to GTK4 for the on-screen keyboard I wrote for the Pinephone. So far nobody is using it though, so it's not urgent :laughing:
1+ I also really would like to see the porting to gtk4 complete :)
Just so y'all know, I'm not actively working on this at the moment. Not to say I won't come back to it, but someone else getting it running on GTK4 wold make it happen a lot sooner. I'll still test, review PRs, make releases, etc.
we can not just use Gdk.wayland and recover its display and or its surface to create this kind of library? I don't know much of wayland or gtk sorry :)
No. GTK creates and draws to a wl_surface
(which you want), but it also attaches that to a xdg_surface
, which you do not want. In order to make a compositor accept a layer shell surface, the surface must not have an xdg_surface
attached to it. Preventing GTK from doing that is where the complexity and GTK hacking arises.
Making popups (including tooltips) work out of the box also raises a bunch of issues.
and we can't simply force him with a new xdg_surface?
I have had an idea ! What if we simply ask the gtk team to add a function to get the xdg_surface? so we can modify it at our child, right?
@hydrasho we cannot, because we need a layer surface, not xdg_surface.
what is that then? I do not understand ! https://valadoc.org/gtk4/Gdk.Wayland.Surface.html
I've been working on some GTK merge requests refactoring the gdksurface-wayland.c
code. And my ideas for how the APIs to support this could work are described in https://gitlab.gnome.org/GNOME/gtk/-/issues/2132#note_1331574.
Really need to implement it to see how it ends up working in practice, but hopefully not too much is needed in GTK to support things like layer-shell without any hacks or private APIs.
@ids1024 thanks for your contributions on that! Be aware that in addition to the problems creating custom shell surfaces introduced in GTK4, there are also problems getting the info needed to create popups. This required hacking GTK even in GTK3 (why gtk-priv exists in this project today).
The way the protocol works for layer shell popups is you make an XDG popup with a null parent, and then set the layer surface as the parent with zwlr_layer_surface_v1.get_popup
. After investigating several ways to do this, the way I settled on for the GTK3 version is to pull the private GTK data used for popup positioning and then use that to re-implement popup creation if we detect that a new window is a popup. As you can see this is rather complicated, brittle, and probably does not result in entirely correct behavior (for example I believe GTK 3 and 4 now support re-layout of popups, but gtk-layer-shell does not).
If you're working with upstream to allow us to only use stable APIs, you need to keep popups in mind as well. Ideally there would be a way to let core GTK create an XDG popup from a non-XDG window, and then expose the popup's xdg_popup
Wayland object before it is initially committed so gtk-layer-shell could set the parent. I don't know if any other protocols work like Layer Shell in this respect, but the xdg-shell protocol was certainly designed with this type of extension in mind so such a GTK feature may be useful beyond this library and those like it. There might be other ways to structure the transaction, but anything that requires us to manage popups as custom surfaces is harder to implement and gives us a larger surface area for bugs.
FYI I'm available to give feedback and can probably find time to port the library to GTK4 if enough lands in GTK to make it easy, but I won't be doing any intensive hacking on this or on GTK in the foreseeable future.
I don't know if any other protocols work like Layer Shell in this respect, but the xdg-shell protocol was certainly designed with this type of extension in mind so such a GTK feature may be useful beyond this library and those like it.
Yep. xdg_surface::get_popup
documents that "If null is passed as a parent, a parent surface must be specified using some other protocol, before committing the initial state.".
So I think a GdkWaylandCustomSurface
type would have to support a callback that runs there, when a popup is created with the custom surface as the parent. It seems reasonable enough to support something like that since it shouldn't require a complicated API and is explicitly how xdg-shell
expects extension protocols to work.
So I think it should be possible to cleanly and correctly handle that.
Another complication is that GtkWindow
is built around GdkToplevel
, so I don't think it would be usable with a GdkWaylandCustomSurface
. In which case there would need to be another widget implementing GtkNative
and GtkRoot
(which are not publicly implementable). I guess that would also lead to a different API from what gtk-layer-shell
provides.
Hm, creating a custom GtkRoot
widget is more complicated than I expected. That requires not only making GtkNative
and GtkRoot
publicly implementable, but the implementation needs to call into several other private APIs. And the event handling logic seems to assume the root widget is a GtkWindow
(GtkDragIcon
, the other root widget, doesn't handle input events). Not sure that's likely to all be made public in Gtk.
I don't think GtkWindow
would work when not backed by a GdkToplevel
, so I guess the other alternative would be for Gtk to include a root widget for custom surfaces. Not sure what the best approach is.
Perhaps you could use GtkWindow
and leave some of it's XDG-specific behavior unimplemented?
A GdkWaylandCustomSurface
could implement GdkToplevel
, but make virtual functions like lower
do nothing. Then I think that would be easy to use with GtkWindow
, if there's also a way to create a GtkWindow
from that custom surface, rather than having it create a normal GdkWaylandToplevel
in realize
.
That could work, but is inelegant, and I'm not sure something like that is likely to be merged into GTK.
@wmww Are there any updates to gtk4 support
I have not been working on this, no
I'm still waiting on review for my second large-ish MR incrementally refactoring the Gdk Wayland surface code: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/4227
And any feedback on the initial prototype in https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/4335. The hard part there seems to be creating a GTK root widget wrapping the custom Gdk surface, and it would help to have upstream feedback on what possible solution would be best and most likely to actually be merged into Gtk.
(I don't think this can really be done without upstream changes to Gtk. Not without considerably worse hacks than the gtk-priv
this is already using, which isn't optimal either.)
No. GTK creates and draws to a wl_surface (which you want), but it also attaches that to a xdg_surface
There's some discussion on the upstream proposal (https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/28#note_1341317) about how layer-shell should inherit from xdg_surface instead of wl_surface.
Pushing the protocol in that direction would be another way round this problem.
Head on over to https://github.com/wmww/gtk4-layer-shell to check it out. Still rough around the edges, but it's mostly functional.
It requires no patches to GTK, and completely drops gtk-priv. Instead, it wraps libwayland functions and changes the Wayland calls made. This way, GTK thinks it's using XDG Shell while libwayland and the compositor see it using Layer Shell. This is hacky to be sure, but it's far less hacky than gtk-priv and allows the library to be much simpler than the GTK3 version ever was, so I'm calling it a win.
My plan is to iron out the kinks and make a first release within a couple weeks. Feel free to play around with it now and open issues, though opening issues isn't necessary for anything in the todo section at the start of the readme.
I'll close this issue once it's released and people are happy with it. cheers!
Wayland was supposed to be more secure than X11, but apparently you've made it easier to hack the platform with a "man in the middle". The most puritanical defenders of Wayland in GNOME are not going to like that.
@wmww Personally I am not a fan of Wayland, so is there any hope for Gtk4 in X11? By the way, congratulations for your success. It's really very hopeful for the future of Gtk desktops and applications that want to be integrated on the desktop from outside.
Personally I am not a fan of Wayland, so is there any hope for Gtk4 in X11?
@lestcape Gtk4 is already native to both x11 and wayland https://docs.gtk.org/gtk4/x11.html
@A-Cloud-Ninja, thanks, but please see, im asking about the support of gtk-layer-shell for Gtk4 on X11, not about the Gtk4 support of X11.
@lestcape but we does not need layer shell for X11, because standard x11 tricks works for any version of GTK.
@A-Cloud-Ninja, thanks, but please see, im asking about the support of gtk-layer-shell for Gtk4 on X11, not about the Gtk4 support of X11.
That's not how any of this works. layer-shell is a wayland, actually wlroots-specific protocol, that has nothing to do with X11.
@A-Cloud-Ninja yes, I wrote the same xD
My idea was to transparent create a widget using the library in both Wayland and X11, not matter where you are, but if that is out of the scope for gtk-layer-shell, that is ok, to me.
EDIT:
That's not how any of this works. layer-shell is a wayland, actually wlroots-specific protocol, that has nothing to do with X11.
@A-Cloud-Ninja: The gtk-layer-shell use INTERNALLY a Wayland protocol called wlr-layer-shell, but this is an implementation details. The real reason of the existence of gtk-layer-shell is just to provide widgets to build desktop components. So, I' m asking if gtk-layer-shell can also provide the same widgets in X11 transparently. It's perfectly possible if that should be wanted and ofcourse the implementation in X11 can not use the wlr-layer-shell protocol. I hope should be more easy to you to understand my comment now.
@A-Cloud-Ninja, thanks, but please see, im asking about the support of gtk-layer-shell for Gtk4 on X11, not about the Gtk4 support of X11.
That's not how any of this works. layer-shell is a wayland, actually wlroots-specific protocol, that has nothing to do with X11.
That might change if this https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/28 gets in. Then upstream may support it themselves as well.
@Beryesa I don't think it will be merged any time soon as GNOME is in a direct opposition to the protocol. So, this is in an undefined state for now: https://github.com/libsdl-org/SDL/issues/7262#issuecomment-1430935751
Without GNOME's approval, the code to support the protocol in GNOME isn't going to magically appear and, at best, what will happen is that GNOME will separate itself from Wayland development. Wayland by itself is a contract where all parts involved need to agree, otherwise you are providing an api that could or could not be satisfy depending on the desktop implementation.
To my knowledge, gnome is not in opposition to the protocol. They just don't want to implement it in their compositor which is totally fine. See here for the details of the acceptance criteria and the different approval variants.
@Consolatis The protocols are there for provide features, like the one this project gtk-layer-shell is providing. Don't implement the protocol in one compositor means the protocol can not be a Wayland stable protocol, because stable means accepted by all parties. The applications can not relay on a unstable protocol to implement a feature, because the feature will exist in one environment and not in the other crashing the app when it run in an environment where the protocol don't exist.
While GNOME is free to decide what it wants in its environment, it is also true to say that GNOME's decision inevitably affects the availability of the protocol as stable, which means that applications that want to work on all Linux desktops cannot rely on the protocol and that therefore you as a user can not receiving the feature, also if you are not using GNOME.
Now, the thread https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/28 is not trying to creating an unstable protocol, because as you can read the protocol have "been known for the last 3 years as wlr-layer-shell". So, the unstable protocol already exist without the approval of GNOME and that is perfectly fine. What is happening there is that they are trying to set the protocol as stable and to be stable is needed the GNOME approval and this will not happens. So, it's perfectly right to said that GNOME opposes it.
What's worse is that for this protocol to make sense, it must not only be implemented by the desktop, but also the toolkit and Gtk is a GNOME toolkit. The decision not to implement it in the toolkit is even worse, because it means that the applications that use the toolkit (the GTK applications) do not have the features available and this is still true even outside the GNOME environment (for example on KDE) when the Gtk application runs. You still dare to say that it's perfectly fine?
layer-shell doesn't make sense as an official wayland protocol. Not every environment needs this kind of protocol.
What's worse is that for this protocol to make sense, it must not only be implemented by the desktop, but also the toolkit and Gtk is a GNOME toolkit.
Literally none of this is true. Gtk3 never had "official" support in any sense for layer shell, yet it worked and still works fine with some hacks to work around it. Now the same is going to be the case (hopefully) with Gtk4. No official "support" anywhere is needed other than the compositors, of which most compositors that aren't gnome support some variation of wlroots protocols, or similarly intended custom protocols. Please at least vaguely understand the tech you're talking about before ranting against it.
Can we please keep the focus on gtk-layer-shell and this issue and not on Wayland, layer-shell or GNOME? @wmww was kind enough to spend time to create gtk-layer-shell and adopt it for GTK4. Everything else is a little out of scope :)
Hi @wmww; this is maybe a stretch topic-wise, but I'm working on a Wayland embedding library (essentially to be able to do XEMBED-like things on Wayland for external-process xfce4-panel applets). I realized that I'd need pointers to a GdkWindow
's xdg_surface
and xdg_toplevel
structs to be able to do some necessary things. While I didn't exactly take inspiration from your gtk-priv stuff in the GTK3 version of layer-shell, I ended up doing something similar, though much simpler as I don't need to change any behavior, and only need to target GTK 3.24, which as I'm sure you know is mostly maintenance-only, so I don't expect the internals to change much, if at all, in the future.
I was pointed here to your different approach for GTK4, and I'm definitely interested in doing something a bit less invasive. The problem, of course, is that if gtk4-layer-shell is intercepting/proxying libwayland-client calls, and my library does the same, and they're in the same process, they will likely step on each other's toes and break each other. So I'd definitely be interested in a library version of what you're doing here!
On a side note, I'd always wondered why you couldn't get away with only using gdk_wayland_window_set_use_custom_surface()
(without further need to dig into internals) for the GTK3 version of layer-shell, as that function seemed to be made essentially for this very use case. Was there something about it that just didn't work right, or didn't expose enough for the layer-shell stuff to work? Of course, it seems GTK4 has removed that function (bummer; I wonder if they'd be interested in re-adding it), so you have no choice for the GTK4 version of layer-shell.
(I could presumably also use this in my library, but then I'd just be creating an xdg_surface
/xdg_toplevel
of my own there, instead of letting GDK do it, and would essentially end up having to duplicate most of the existing GdkWaylandWindow
code in my library, which I'm not thrilled about doing. Of course, the poke-into-GDK-internals hack isn't something I'm thrilled with either.)
Wow, this issue really popped off over the weekend.
@kelnos: good to know there's interest in a library version of the libwayland hacks. The public GTK3 APIs always had limitations, the biggest one of which is that I couldn't support popups using only them. A large part of the complexity of this library is in order to support popups. If you have more questions I encourage you to start a GitHub "discussion" either on this repo or the gtk4-layer-shell one.
That goes for everyone, please open new issues for new issues or start new discussion threads for things that aren't issues. Not everything has to be posted in #37.
I've wanted to use GTK4 in my project, but settled for GTK3 because of gtk-layer-shell. However, it turns out (after a lot of work) that GTK3 is not usable for my needs without considerable amount of ugly hacks.
Is GTK4 support planned, and if so, is it in progress / what are the blockers for the work being started?