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

Macos backend needs a window delegate to capture events. #100

Open
geon opened this issue Oct 28, 2024 · 4 comments
Open

Macos backend needs a window delegate to capture events. #100

geon opened this issue Oct 28, 2024 · 4 comments

Comments

@geon
Copy link
Contributor

geon commented Oct 28, 2024

I have some code halfway working in a branch, but I'm not sure how Capy works internally.

https://github.com/geon/capy/tree/window-delegate

@zenith391
Copy link
Member

What's not working in your code? Also if you have any question for how Capy works, you can just ask me on capy's Matrix channel or on my Discord (although I'm more active on Discord)

@geon
Copy link
Contributor Author

geon commented Oct 30, 2024

I was getting garbage data in the window size.

I think the getEventUserData isn't properly implemented. If I understand it correctly, it should return a separate object for each widget, while the macos backend only has one global object.

I think Capy uses native apis in both gtk and win32 apis for attaching custom data to widgets, but I'm not aware of something similar in macos. Perhaps we could just have a global hashmap, with the peer as key? Or would that leak?

@zenith391
Copy link
Member

I think the getEventUserData isn't properly implemented. If I understand it correctly, it should return a separate object for each widget

Yea that's what getEventUserData should do.

I think Capy uses native apis in both gtk and win32 apis for attaching custom data to widgets, but I'm not aware of something similar in macos. Perhaps we could just have a global hashmap, with the peer as key? Or would that leak?

You can absolutely use a global hashmap for this usecase. Although, for the WebAssembly backend, when I faced the same problem, I ended up replacing the peer object by a manually allocated GuiWidget, which basically contains EventUserData's fields, alongside the actual peer object (which would be objc.Object).

So for the macOS backend, this would be equivalent to replacing, in Label and in Container, the field peer: objc.Object by peer: GuiWidget.
And creating the struct:

const GuiWidget = struct {
  object: objc.Object,
  // Either include EventUserData or just copy its fields. Although including
  // it might be better.
  data: EventUserData,
};

Then in Label.init and Container.init, you allocate an instance of GuiWidget and fill in the data.

@geon
Copy link
Contributor Author

geon commented Nov 2, 2024

I don't really see how the GuiWidget struct helps.

in https://github.com/geon/capy/blob/1a22e734cb0fdd4504b388f11bf675a80dc40b29/src/backends/macos/CapyWindowDelegate.zig#L20 , I get access to the NSWindow, , but in the windowDidResize callback I can't use any kind of closure to access the GuiWidget outside the callback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants