Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't crash when popups are created on session lock surfaces #67

Merged
merged 11 commits into from
Jan 29, 2025
3 changes: 3 additions & 0 deletions examples/session-lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ static void activate(GtkApplication* app, void *data) {
g_signal_connect(button, "clicked", G_CALLBACK(unlock), app);
gtk_box_append(GTK_BOX(box), button);

// Not displayed, but allows testing that creating popups doesn't crash GTK
gtk_widget_set_tooltip_text(button, "Foo Bar Baz");

gtk_window_set_child(GTK_WINDOW(gtk_window), box);
gtk_window_present(gtk_window);
}
Expand Down
9 changes: 8 additions & 1 deletion src/gtk4-session-lock.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "gtk4-session-lock.h"
#include "session-lock.h"
#include "lock-surface.h"
#include "registry.h"
#include "libwayland-shim.h"
Expand All @@ -20,6 +21,7 @@ gboolean gtk_session_lock_is_supported() {

struct _GtkSessionLockInstance {
GObject parent_instance;
void* wayland_object;
gboolean is_locked;
gboolean has_requested_lock;
gboolean failed;
Expand Down Expand Up @@ -111,6 +113,7 @@ gboolean gtk_session_lock_instance_lock(GtkSessionLockInstance* self) {

self->has_requested_lock = TRUE;
session_lock_lock(wl_display, session_lock_locked_callback_impl, self);
self->wayland_object = self->failed ? NULL : (void*)session_lock_get_active_lock();
return !self->failed;
}

Expand Down Expand Up @@ -160,7 +163,11 @@ static struct lock_surface_t* lock_surface_hook_callback_impl(struct wl_surface*
static void on_window_mapped(GtkWindow *window, gpointer data) {
(void)window;
struct gtk_lock_surface_t* self = data;
lock_surface_map(&self->super, self->lock);
if (self->lock->wayland_object == session_lock_get_active_lock()) {
lock_surface_map(&self->super);
} else {
g_warning("Not showing lock surface because the session lock it is linked to is not active");
}
}

void gtk_session_lock_instance_assign_window_to_monitor(
Expand Down
4 changes: 4 additions & 0 deletions src/libwayland-shim.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ struct wl_display* libwayland_shim_proxy_get_display(struct wl_proxy* proxy) {
return proxy->display;
}

struct wl_event_queue* libwayland_shim_proxy_get_queue(struct wl_proxy* proxy) {
return proxy->queue;
}

// Returns true if any arguments are proxies created by us(not known to libwayland)
static bool args_contains_client_facing_proxy(
struct wl_proxy* proxy,
Expand Down
2 changes: 2 additions & 0 deletions src/libwayland-shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ void* libwayland_shim_get_client_proxy_data(struct wl_proxy* proxy, void* expect
// Yes wl_proxy_get_display exists, but only in libwayland >=1.23. This can be replaced with that once we can drop
// support for older libwaylands (though no rush, this works)
struct wl_display* libwayland_shim_proxy_get_display(struct wl_proxy* proxy);
// Same deal, wl_proxy_get_queue() exists but is new
struct wl_event_queue* libwayland_shim_proxy_get_queue(struct wl_proxy* proxy);

#define LIBWAYLAND_SHIM_FIRST_ARG(first, ...) first
#define LIBWAYLAND_SHIM_DISPATCH_CLIENT_EVENT(listener, event, ...) \
Expand Down
Loading