To avoid looking for a solution to an XY problem, I will first explain what my ultimate goal is: I am working on an X11 screen lock application that I’m migrating from GTK3 to GTK4. To prevent the window manager from messing with the window, I first enable the “override redirect” and then grab keyboard and mouse. In GTK3, using gtkmm, I was able to do it like this:
get_window()->set_override_redirect(true);
const auto grabSuccess =
get_display()->get_default_seat()->grab(get_window(), Gdk::SEAT_CAPABILITY_ALL, true);
if (grabSuccess != Gdk::GRAB_SUCCESS) {
throw padlock::Exception("Device grab failed with an error ('{}')", std::to_string(grabSuccess));
}
This code took care of overriding the WM and keyboard + mouse grabbing, while forwarding the X11 events to my GTK widgets (Gtk::Entry
).
After reading the GTK3 to GTK4 migration notes, I realized that I’m on my own now with both the WM overriding and keyboard + mouse grabbing. I was successfully able to override the WM by using libX11 directly and grab the mouse and keyboard:
static void set_override_redirect(GdkSurface* surface, bool enable) {
Display* display = GDK_SURFACE_XDISPLAY(surface);
Window x11_window = GDK_SURFACE_XID(surface);
XSetWindowAttributes attrs;
attrs.override_redirect = enable ? True : False;
XChangeWindowAttributes(display, x11_window, CWOverrideRedirect, &attrs);
XFlush(display);
}
static bool grab_pointer(GdkSurface* surface) {
... // omitted for brevity
}
static bool grab_keyboard(GdkSurface* surface) {
Display* display = GDK_SURFACE_XDISPLAY(surface);
Window x11_window = GDK_SURFACE_XID(surface);
const int result = XGrabKeyboard(display, x11_window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
return result == GrabSuccess;
}
This all seems to work fine, but now, I have been stuck on forwarding the X11 events to GTK/GDK. I understand that ultimately, the goal in GTK is to abstract the platform specific functionality away from the library, but I can’t find any mechanism that I could use to create new GDK events.
Did I just miss something or is it a correct conclusion to draw that it’s not possible in GTK4? Or did I approach the problem from a completely wrong angle in the first place?
I should also mention that the motivation to migrate from GTK3 to GKT4 was one, that GTK4 implements PasswordEntryBuffer
, which mlock
s its buffer and thus makes the application more secure, and two, I want to stay more up-to-date with the dependencies.
So to summarize my question: how can I migrate from GTK3 to GTK4 while maintaining all the functionality from my GTK3 application?
I would appreciate any pointers!