wmww / gtk4-layer-shell

A library to create panels and other desktop components for Wayland using the Layer Shell protocol and GTK4
MIT License
128 stars 4 forks source link

Setting tooltip on a widget then hovering over it segfaults. #24

Open Aylur opened 11 months ago

Aylur commented 11 months ago

Hey, thank you for this library. I have an issue just as the title says. It happens on Hyprland. Tested it on Sway and there it works with a warning message "Gdk warning: Compositor doesn't support moving popups, relying on remapping".

here is an example

imports.gi.versions.Gtk = '4.0';
const { Gtk, Gtk4LayerShell } = imports.gi;

const app = new Gtk.Application();
app.connect('activate', () => {
    const label = new Gtk.Label({
        label: 'hello',
        tooltipText: 'crash',
    });

    const win = new Gtk.Window({
        application: app,
        defaultWidth: 100,
        defaultHeight: 100,
        child: label,
    });

    Gtk4LayerShell.init_for_window(win);
    win.present();
});
app.run(null);

what other information can I provide that would be useful? Should I also open an issue on Hyprland?

wmww commented 10 months ago

Hi, sorry for the wait. I tried to reproduce but was unable to. Tooltip appears and moves around with no crash for me. Distro: Arch gtk4-layer-shell: current main (same commit as 1.0.1) gtk: 4.12.1 gjs: 1.76.2 hyprland: 0.29.0 Command: GI_TYPELIB_PATH=build/src LD_PRELOAD=build/src/libgtk4-layer-shell.so WAYLAND_DISPLAY=wayland-1 gjs ./crash.js

Please let me know if you can still reproduce this bug, and what your versions of things are.

EDIT: I think I found both your bug and the fix for it in #27. If you get a chance please test with current main and let me know if there are still crashes. Testing with gtk4-layer-shell 1.0.1 is no longer useful.

Aylur commented 10 months ago

Running with Gtk 4.10 still segfaults using #27. Updating Gtk to 4.12 is what solves it, on 4.12 it doesn't crash with the 1.0.1 either

wmww commented 8 months ago

I have managed to reproduce, however it appears this happens even when GTK-layer-shell is not used (when you comment out Gtk4LayerShell.init_for_window(win);). My guess is the popup repositioning is an obscure API that Hyprland has stricter requirements for than other compositors, and there was a GTK bug with that that was fixed recently. In any case, not a problem with this library.

pdf commented 6 months ago

@wmww I can't reproduce your findings - given the following minimal application (fair warning, I don't write C but wanted to produce a minimal case), with the call to gtk_layer_init_for_window the application segfaults on displaying the tooltip, without it there is no crash.

#include <gtk4-layer-shell/gtk4-layer-shell.h>
#include <gtk/gtk.h>

static void activate (GtkApplication* app, gpointer user_data)
{
  GtkWidget *window;
  GtkWidget *label;

  window = gtk_window_new();
  gtk_window_set_application(GTK_WINDOW (window), app);
  label = gtk_label_new("label");
  gtk_widget_set_tooltip_text(label, "crash");
  gtk_window_set_child(GTK_WINDOW (window), label);

  gtk_layer_init_for_window(GTK_WINDOW (window));

  gtk_window_present(GTK_WINDOW (window));
}

int main (int argc, char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new("org.gtk.glstest", G_APPLICATION_DEFAULT_FLAGS);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run(G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

gtk4 version: 4.12.4 gtk4-layer-shell version: 1.0.2 hyprland version: 0.33.1

pdf commented 6 months ago

Okay, something weird is going on here - if I build gtk4-layer-shell locally and use the locally compiled lib via LD_LIBRARY_PATH to run the example binary there's no crash, but if I use the lib installed via my package manager (arch AUR) the segfault occurs.

wmww commented 6 months ago

Are you sure the version you have installed is v1.0.2? If so, that would be strange indeed.

pdf commented 6 months ago

Yes it's v1.0.2, I worked out that if I build in a chroot it segfaults consistently, but if I build on the host using the same tooling it does not, which says something in the build environment is affecting the output (the lib output varies in size and binary content slightly between the two envs, though they both link to all the same libs).

Looking at the difference in build output, in the chroot meson says that it does not find cmake or wayland-protocols (though this is noted as a run-time dependency when present on the host), should these be build-time dependencies? If so I'll report to the package maintainer.

wmww commented 6 months ago

I just installed gtk4-layer-shell from the AUR (via yay) and tested the above C code on Hyprland and sway. Doesn't crash on my machine.

pdf commented 6 months ago

I just installed gtk4-layer-shell from the AUR (via yay) and tested the above C code on Hyprland and sway. Doesn't crash on my machine.

I use paru with chroot mode enabled to isolate builds from the host. When building in a chroot, only those dependencies listed in the PKGBUILD are installed. Since this works for you via yay, I suspect that whatever dep is missing from the PKGBUILD that causes the resulting library to crash is already present on your system.

wmww commented 5 months ago

Installed gtk4-layer-shell built in a chroot using paru --chroot -S gtk4-layer-shell, still no crash

pdf commented 5 months ago

Hmm, I can still repro reliably, is there something I can do to help diagnose? I'm not sure that I can build layer-shell with debug symbols since I need to build via the paru chroot to trigger it.

wmww commented 5 months ago

You could run it and make it crash with WAYLAND_DEBUG=1 and upload the log. Maybe that would help me identify some difference between our setups at runtime. No rush, it will probably take me some time to get to this. If anyone else is encountering the same problem, please speak up or 😕 react, I'll try to prioritize this higher if it's effecting multiple people and nobody else can figure it out.

pdf commented 5 months ago

I worked out how to disable stripping in makepkg, here's the stack trace:

#0  0x00007bdb32a10a60 in wl_argument_from_va_list.constprop () at /usr/lib/libgtk4-layer-shell.so.0
#1  0x00007bdb32a10e61 in wl_proxy_marshal_flags () at /usr/lib/libgtk4-layer-shell.so.0
#2  0x00007bdb325fda5f in xdg_popup_reposition (token=1, positioner=0x5cd54f80dc10, xdg_popup=0x5cd54f80d8c0) at ./gdk/wayland/xdg-shell-client-protocol.h:2299
        positioner = 0x5cd54f80dc10
        surface = 0x5cd54f792170 [GdkWaylandPopup]
        wayland_surface = 0x5cd54f792170 [GdkWaylandPopup]
        __func__ = "gdk_wayland_surface_present_popup"
#3  do_queue_relayout (layout=<optimized out>, height=<optimized out>, width=<optimized out>, wayland_popup=0x5cd54f792170 [GdkWaylandPopup]) at ../gtk/gdk/wayland/gdkpopup-wayland.c:1190
        positioner = 0x5cd54f80dc10
        surface = 0x5cd54f792170 [GdkWaylandPopup]
        wayland_surface = 0x5cd54f792170 [GdkWaylandPopup]
        __func__ = "gdk_wayland_surface_present_popup"
#4  reposition_popup (layout=<optimized out>, height=<optimized out>, width=<optimized out>, wayland_popup=0x5cd54f792170 [GdkWaylandPopup]) at ../gtk/gdk/wayland/gdkpopup-wayland.c:1343
        surface = 0x5cd54f792170 [GdkWaylandPopup]
        wayland_surface = 0x5cd54f792170 [GdkWaylandPopup]
        __func__ = "gdk_wayland_surface_present_popup"
#5  gdk_wayland_surface_present_popup (wayland_popup=0x5cd54f792170 [GdkWaylandPopup], width=<optimized out>, height=<optimized out>, layout=<optimized out>) at ../gtk/gdk/wayland/gdkpopup-wayland.c:1409
        surface = 0x5cd54f792170 [GdkWaylandPopup]
        wayland_surface = 0x5cd54f792170 [GdkWaylandPopup]
        __func__ = "gdk_wayland_surface_present_popup"

WAYLAND_DEBUG logs attached, but doesn't seem super-interesting, comparing segfaulting version to the non-segfaulting version.

gtk4-layer-shell-waland_debug.log gtk4-layer-shell-waland_debug-nocrash.log

Rayzeq commented 1 month ago

I also have this issue on Nixos, adding wayland-protocols as a build dependency solves it. Here's how to do it for those who need it:

the-variable-you-want-to-put-your-package-in = with pkgs; [
  (gtk4-layer-shell.overrideAttrs (oldAttrs: {
    nativeBuildInputs = oldAttrs.nativeBuildInputs ++ [ wayland-protocols ];
  }))
];