Skip to content

Commit

Permalink
Merge pull request #67 from wmww/session-lock-popups
Browse files Browse the repository at this point in the history
Don't crash when popups are created on session lock surfaces
  • Loading branch information
wmww authored Jan 29, 2025
2 parents e89e8cd + dc22920 commit 8537212
Show file tree
Hide file tree
Showing 21 changed files with 524 additions and 258 deletions.
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

0 comments on commit 8537212

Please sign in to comment.