david-vanderson/dvui

A few bugs/problems

Closed this issue · 21 comments

Hello!

First off, I wanted to say: thank you for making such GUI framework! It is amazing!!

With that said, I did encounter a few bugs and problems:

  • Trying to move any dialog window (so, a child window inside the main SDL window) causes a segmentation fault:
Segmentation fault at address 0x8
???:?:?: 0x7fec3bf66be0 in ??? (???)

Unfortunately, it doesn't give me any more information... is there a way to make it do so, or is it the maximum it can give? It seems pretty unhelpful...

  • When closing the window (and thus, quitting the program), it seems like there is some leaked memory from the GPA:
error(gpa): memory address 0x7f0ba42b4000 leaked: 
???:?:?: 0x34d08c in ??? (???)
???:?:?: 0x301b14 in ??? (???)
???:?:?: 0x2de9e5 in ??? (???)
???:?:?: 0x2e5bd6 in ??? (???)


error(gpa): memory address 0x7f0ba0ad6000 leaked: 
???:?:?: 0x35832b in ??? (???)
???:?:?: 0x3161e0 in ??? (???)
???:?:?: 0x2e27ed in ??? (???)
???:?:?: 0x2deb0a in ??? (???)


error(gpa): memory address 0x7f0ba42b3000 leaked: 
???:?:?: 0x34d8c9 in ??? (???)
???:?:?: 0x302140 in ??? (???)
???:?:?: 0x2deaf9 in ??? (???)
???:?:?: 0x2e5bd6 in ??? (???)


error(gpa): memory address 0x7f0bad5ab000 leaked: 
???:?:?: 0x3b081e in ??? (???)
???:?:?: 0x3a2362 in ??? (???)
???:?:?: 0x38dcd5 in ??? (???)
???:?:?: 0x36ebb5 in ??? (???)

I don't think it provides from my program, I double checked everything and I'm freeing all the memory I'm allocating. In fact, because of that, I don't even know where these memory leaks are coming from... are they coming from the framework itself?

  • The standalone SDL on the repository doesn't compile. There seems to have been a typo or something: at line 69, there is this:
var scroll = try gui.scrollArea(@src(), .{ .expand = .both, .color_style = .window });

However, this is incorrect, as it requires 3 arguments instead of 2. Here, the initialization options are missing. This is correct, however:

var scroll = try gui.scrollArea(@src(), .{}, .{ .expand = .both, .color_style = .window });
  • And finally, the standalone SDL demo in the gui-demo repository doesn't compile. Unfortunately, I haven't been able to figure this one out:
error: deprecated; use @memset instead
pub const set = @compileError("deprecated; use @memset instead");

However, I did notice that the repository uses an old version of gui (as can be seen by the commit hash inside the build.zig.zon file). I've tried updating the version (by changing the commit hash), but it still didn't work...

Anyway, sorry for this big wall of text, and again, thank you for this amazing library!

Thank you very much for trying it out! Sorry you ran into a bunch of bugs.

Can you tell me what platform (Windows, Mac, Linux) and zig version you are using? Are you using zig build within the gui repo checkout to compile, or maybe the gui-demo repo? (Sorry I haven't updated it yet - good catch)

The lack of info in those stack traces maybe indicates a version of zig compiled without debug info? How did you get your zig?

That last error about memset is a recent change to zig - I'll fix that when I update the gui-demo repo. Thanks!

Sorry you ran into a bunch of bugs.

That's fine, don't worry!

Can you tell me what platform (Windows, Mac, Linux) and zig version you are using?

I'm using Linux, with Zig 0.11.0-dev.3363+9461ed503.

Are you using zig build within the gui repo checkout to compile, or maybe the gui-demo repo?

I'm using zig build run-standalone-sdl on both, so technically yes.

How did you get your zig?

Since my distribution packages Zig 0.10, I downloaded Zig from https://ziglang.org/download.

I've pushed fixes for the compile errors (hopefully). Do you still get them?

I've been unable to replicate the crashes you are seeing so far. Would you mind trying with a newer version of zig? I just tested with 0.11.0-dev.3380+7e0a02ee2

I'm also on Linux (Mint, x86_64). Can you provide the output of uname -a and cat /etc/os-release? What version of SDL is installed?

I should have answered your issue about updating the build.zig.zon version. The way I know how to do it is to get the git commit sha and put that in the url field (...archive/<sha>.tar.gz), and comment out the hash line. Then zig build will give you a message like this:

/home/dvanderson/code/gui-demo/build.zig.zon:6:20: error: url field is missing corresponding hash field
            .url = "https://github.com/david-vanderson/gui/archive/872ee60c125efd297391f615ed794f50414cc25b.tar.gz",
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: expected .hash = "1220731b7b5344ef52b6ab9c784330496f12b1bdbfcb615b0741c0148107166a3584",

and you can copy that new hash into the hash line. Make sense?

Thanks!

I've pushed fixes for the compile errors (hopefully). Do you still get them?

Nope, they're all gone now! (Including on gui-demo)

I've been unable to replicate the crashes you are seeing so far. Would you mind trying with a newer version of zig? I just tested with 0.11.0-dev.3380+7e0a02ee2

I just tried with that exact same version and, unfortunately, I still get the exact same Segmentation fault error.

Can you provide the output of uname -a and cat /etc/os-release? What version of SDL is installed?

uname -a:

Linux shininglea 6.1.31_1 #1 SMP PREEMPT_DYNAMIC Wed May 31 05:53:37 UTC 2023 x86_64 GNU/Linux

cat /etc/os-release:

NAME="Void"
ID="void"
PRETTY_NAME="Void Linux"
HOME_URL="https://voidlinux.org/"
DOCUMENTATION_URL="https://docs.voidlinux.org/"
LOGO="void-logo"
ANSI_COLOR="0;38;2;71;128;97"

DISTRIB_ID="void"

sdl2-config --version:

2.26.5

The way I know how to do it is to get the git commit sha and put that in the url field (...archive/.tar.gz), and comment out the hash line.

Huh, that's interesting, because I had did just that but it didn't give this error at all. Instead, it tried to compile and failed on a FreeType error, if I recall correctly (I forgot if it was the same...)

I will try to reproduce. Are you using Void Linux XFCE musl or glibc?

I'm using Void Linux with glibc (not XFCE though but that shouldn't matter)

I can't reproduce the error. It works for me on the Void Linux live and also after installation and updating. I'm unsure what to try at this point.

Can you try with a Void Linux live session (booted from usb)? I only had to install xz and git and SDL2-devel, then download zig, git clone gui-demo and zig build run-standalone-sdl - any luck with that?

Alright, I was able to solve the Segmentation fault issue! Turns out it's an issue of my WM (labwc)... Not sure if it's because of Wayland or not, since I tried with XFCE and that uses X11.

It also seems like the leaked memory is coming from my own program, so my bad!

I still wonder why I can't seem to get any stack trace or something... are the Zig binaries on their website not compiled with debug info?

They should be. I get a stack trace when I cause a crash in Void. You can put this somewhere to cause a crash intentionally:

var num: ?i32 = null;
std.debug.print("crash {d}\n", .{num.?});

Do you get a stack trace in the Void live usb?

Wow, I do get a stack trace... I tested with my program and it also does show the stack trace, but it doesn't on my main install... what the hell??!!

Haha that's my reaction as well. I don't have much insight here, except to guess that there's some kind of package incompatibility down at the glibc level?

Separately, I'd love to get any feedback about the library itself. Are there a few things that were/are confusing we could improve?

there's some kind of package incompatibility down at the glibc level?

Both systems are up-to-date, so I don't think it's that, but at the same time, I have no idea...

Are there a few things that were/are confusing we could improve?

Well, I personally thinks it lacks controls (ComboBox for example). I do have some issues making the GUI itself though, like for example how would you make a sort of "split container" layout (a box of controls that takes all the vertical space at teh left, and also one at the right)?
Similarly, I was trying to make a simple menu bar at the top with a scroll area that takes up the rest of the space but I was unable to do so. This might just be a particularity of immediate mode GUIs, this is the first time I actually try one of those (and I love them!), but at the same time, I'm really bad at making/designing GUIs... :P

Thanks for the feedback! I've updated the readme to include a status and a list of missing widgets.

For the split container layout, were you able to see the demo window with the section on layout? If you did, were the examples there not clearly what you wanted? Maybe I need to rework that part?

There is not a direct part of the demo that shows how to do the menu at the top and scroll underneath - I will add that. Thanks!

were you able to see the demo window with the section on layout?

Yes, but I unfortunately wasn't able to make exactly what I wanted. Here's a rough idea of what I want to do (pardon the extremely bad drawing):

screenshot

Ah okay. You want something like this:

    {
        var hbox = try gui.boxEqual(@src(), .horizontal, .{ .expand = .horizontal, .min_size_content = .{ .h = 200 } });
        defer hbox.deinit();

        {
            var vbox1 = try gui.box(@src(), .vertical, .{ .expand = .both });
            defer vbox1.deinit();
            _ = try gui.button(@src(), "vbox1 first", .{});
            _ = try gui.button(@src(), "vbox1 second", .{});
        }

        {
            var vbox2 = try gui.box(@src(), .vertical, .{ .expand = .both });
            defer vbox2.deinit();
            _ = try gui.button(@src(), "vbox2 first", .{});
            _ = try gui.button(@src(), "vbox2 second", .{ .expand = .both });
        }
    }

You can put this code at the bottom of gui_frame() in standalone-sdl.zig. The min_size_content is needed in this context because you can't expand vertically inside a vertical scroll area. I'll think about how to relax that requirement.

Does this help?

Does this help?

It does! Thank you so much!! But I do have 2 final things to ask:

  • How would you reduce the width of one of the boxes? For example, I'd like the left vertical box to take slightly less horizontal space than the right one. However, I could only find a minimum size content, not a maximum one. Is there a way to do this?

  • This might be a thing of immediate mode GUIs, but I'm really confused about one thing. See, I tried the code to put a menu bar at the top of my application along with a scroll area, and it worked. But, I noticed you put that code in a sort of "code block". Since I don't naturally use these, I removed the code block, thinking it was just some cosmetic thing. But it actually fricked up my whole layout. And I think this is similar with functions and loops: why do I have to put an extra ID when putting some GUI code in a function or a loop and calling it multiple times, whereas I don't need to do such thing if I manually copy the code multiple times? I don't understand...

Great questions!

  • Usually in this kind of situation, you want one box to be just big enough for it's children (the default) and the other to take all the space (.expand = .horizontal). That works in a normal gui.box - gui.boxEqual is for when you want all the children to have the same space. So I would change the hbox boxEqual to a normal box and play around with the .expand values. There's no way to specify a maximum size.
  • The "code block" is about getting the widgets parent/child relationships right. I need to add some docs for this. How's this:
var hbox = try gui.box(@src(), .horizontal, .{ .expand = .horizontal });
// now hbox is the current parent widget
var vbox1 = try gui.box(@src(), .vertical, .{ .expand = .both });  // child of hbox
// now vbox1 is the parent
_ = try gui.button(@src(), "vbox1", .{});  // child of vbox1
vbox1.deinit();
// now we are back to hbox being the parent
_ = try gui.button(@src(), "hbox button", .{});  // second child of hbox
hbox.deinit();
// nothing after this will be inside hbox

This works but it's easy to forget putting the deinit() calls in the right place, so with zig's defer we can do:

{
  var hbox = try gui.box(@src(), .horizontal, .{ .expand = .horizontal });
  // now hbox is the current parent widget
  defer hbox.deinit();  // will be called at the closing brace
  {
    var vbox1 = try gui.box(@src(), .vertical, .{ .expand = .both });  // child of hbox
    // now vbox1 is the parent
    defer vbox1.deinit();
    _ = try gui.button(@src(), "vbox1", .{});  // child of vbox1
  }

  // now we are back to hbox being the parent
  _ = try gui.button(@src(), "hbox button", .{});  // second child of hbox
}
  • The .id_extra stuff is to give widgets unique ids, which are used to keep state from frame to frame. The id is derived from the current parent widget id, the @src() parameter, and any .id_extra given. @src() is enough to give unique ids as long as the widgets us different source lines in the code. If you use a loop, then @src() will be the same each time through the loop, so you need to pass .id_extra to ensure unique ids.

Is this starting to make sense?

I would change the hbox boxEqual to a normal box and play around with the .expand values

Ah yeah, just changing boxEqual to box makes things better. I'll probably keep it this way. Thanks!

Is this starting to make sense?

It does! I understand now! :D

This aside, it looks like the Segmentation fault which happened earlier is not actually due to my WM. I tested in a VM with the exact same WM and it works just fine... this is even weirder... no stack traces and random segmentation faults?? What is wrong with my install? xD

@david-vanderson I have fixed the segmentation fault issue on my install...

I debugged with GDB and found out it was faulting in SDLBackend.zig at line 111. That line is:

c.SDL_SetCursor(cur);

So I commented it, and now it works! I can now move floating windows! I still wonder why it doesn't happen in a VM with the exact same distribution and WM... how odd...

EDIT: It seems to be working fine when SDL_VIDEODRIVER is set to x11 instead of wayland... Which then made me remember I didn't set this variable to wayland in the VM, which means it is most likely an issue with my WM, or simply an SDL2 Wayland bug...

I believe all issues are mostly resolved! I still need to investigate the no stack trace issue though... but I'll close this issue.