wmww / gtk4-layer-shell

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

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

Closed Aylur closed 1 month ago

Aylur commented 1 year 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 1 year 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 1 year 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 1 year 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 11 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 11 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 10 months ago

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

pdf commented 10 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 10 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 10 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 10 months ago

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

pdf commented 10 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 10 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 10 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 6 months 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 ];
  }))
];
pdf commented 3 months ago

~All tooltips now seem to crash under Hyprland, regardless of what dependencies are available at build time. A number of changes have occurred in that compositor in recent times to remove wlroots as a dependency though, so it's possible those changes are related, but it seems likely something wonky is happening here at the protocol level.~

Sorry for the noise, I was mistaken - I rebuilt gls on the host and it is working again.

Fuhrmann commented 2 months ago

I'm experiencing the same problem today after updating gtk4-layer-shell:

System/Version info ```sh ➜ gtk4-seg-fault git:(master) ✗ uname --all Linux archy 6.10.9-arch1-2 #1 SMP PREEMPT_DYNAMIC Tue, 10 Sep 2024 14:37:32 +0000 x86_64 GNU/Linux ➜ gtk4-seg-fault git:(master) ✗ pacman -Qi gtk4-layer-shell Name : gtk4-layer-shell Version : 1.0.3-1 Description : Library to create panels and other desktop components for Wayland Architecture : x86_64 URL : https://github.com/wmww/gtk4-layer-shell Licenses : MIT Groups : None Provides : None Depends On : gtk4 wayland Optional Deps : None Required By : None Optional For : None Conflicts With : None Replaces : None Installed Size : 200.36 KiB Packager : Brett Cornwall Build Date : Wed 11 Sep 2024 10:00:34 PM -04 Install Date : Fri 13 Sep 2024 10:48:11 PM -04 Install Reason : Explicitly installed Install Script : No Validated By : Signature ➜ gtk4-seg-fault git:(master) ✗ pacman -Qi hyprland Name : hyprland Version : 0.43.0-1 Description : a highly customizable dynamic tiling Wayland compositor Architecture : x86_64 URL : https://github.com/hyprwm/Hyprland Licenses : BSD-3-Clause Groups : None Provides : None Depends On : cairo aquamarine libaquamarine.so=3-64 gcc-libs glibc glib2 libgobject-2.0.so=0-64 glslang hyprcursor libhyprcursor.so=0-64 hyprlang libhyprlang.so=2-64 hyprutils libhyprutils.so=1-64 libdisplay-info libdisplay-info.so libdrm libglvnd libEGL.so=1-64 libGLESv2.so=2-64 libOpenGL.so libinput libliftoff libliftoff.so libx11 libxcb libxcomposite libxcursor libxfixes libxkbcommon libxkbcommon.so=0-64 libxrender mesa opengl-driver pango libpango-1.0.so=0-64 libpangocairo-1.0.so=0-64 pixman libpixman-1.so=0-64 seatd libseat.so systemd-libs libsystemd.so tomlplusplus libtomlplusplus.so libudev.so vulkan-icd-loader vulkan-validation-layers wayland libwayland-client.so libwayland-server.so=0-64 wayland-protocols xcb-proto xcb-util xcb-util-errors xcb-util-image xcb-util-keysyms xcb-util-renderutil xcb-util-wm xorg-xinput xorg-xwayland Optional Deps : cmake: to build and install plugins using hyprpm [installed] cpio: to build and install plugins using hyprpm meson: to build and install plugins using hyprpm [installed] Required By : None Optional For : None Conflicts With : None Replaces : None Installed Size : 8.61 MiB Packager : Caleb Maclennan Build Date : Sun 08 Sep 2024 03:24:36 PM -04 Install Date : Sun 08 Sep 2024 09:09:38 PM -04 Install Reason : Explicitly installed Install Script : No Validated By : Signature ```

I can reproduce the problem with this bare minimal application. When I hover over the button with the tooltip I get a segfault:

Application ```rust use gtk4::prelude::ApplicationExt; use gtk4::prelude::ApplicationExtManual; use gtk4::prelude::GtkWindowExt; use gtk4::prelude::WidgetExt; use gtk4::Application; use gtk4::ApplicationWindow; use gtk4::Button; use gtk4_layer_shell::LayerShell; pub fn main() { let app = Application::builder().application_id("test.com").build(); app.connect_startup(move |app| { let window = ApplicationWindow::new(app); window.set_default_size(-1, 50); window.init_layer_shell(); window.auto_exclusive_zone_enable(); window.set_anchor(gtk4_layer_shell::Edge::Left, true); window.set_anchor(gtk4_layer_shell::Edge::Top, true); window.set_anchor(gtk4_layer_shell::Edge::Right, true); let button = Button::with_label("Open child panel"); button.set_tooltip_text(Some("teste")); window.set_child(Some(&button)); app.connect_activate(move |_| window.show()); }); app.run(); } ``` ```toml [package] name = "gtk4-seg-fault" version = "0.1.0" edition = "2021" [dependencies] gdk4 = "0.9.0" gtk4 = "0.9.1" gtk4-layer-shell = "0.4.0" ```

If I comment out the layer shell initialization the tooltip works. Here are the logs, hope it helps.

coredump.log segfault.log gdb.log

pdf commented 2 months ago

The Arch package needs depends on wayland-protocols (or perhaps just builddepends, it's not easy for me to test what happens if wayland-protocols is missing at runtime).

Since the package has moved from AUR into the official Extra repository, this will need to be reported against the official gtk4-layer-shell package. Unforunately since the move of the Arch package issue tracker to Gitlab, manual approval for signups to the tracker is required and I'm waiting for approval so I can't lodge an issue currently.

@wmww perhaps it would be a good idea to mark wayland-protocols as a hard dependency in the build to avoid the possibility that this occurs again in future?

pdf commented 2 months ago

Issue lodged against gtk4-layer-shell in Arch: https://gitlab.archlinux.org/archlinux/packaging/packages/gtk4-layer-shell/-/issues/1

ainola commented 2 months ago

Thanks for bringing this up! I've added it to the makedeps and the new 1.0.3-2 version should hopefully have that fixed. I must have overlooked something when I was testing :(

Fuhrmann commented 2 months ago

1.0.3-2 fixes the problem for me, thank you very much!

wmww commented 1 month ago

I have finally managed to reproduce. It appears that the copy of xdg-shell.xml I keep in the repo is out of date, and when proxying requests this causes problems. Will mark wayland-protocols as a required build dependency and remove xdg-shell.xml from this repo. Thanks everyone for getting to the bottom of it.

EDIT: in the next release the library will not build without system wayland-protocols, but having wayland-protocols installed on the system buidling gtk4-layer-shell should fix this issue for any version.